@greenpandastudios/aug-cli 0.19.0 → 0.20.1
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/README.md +9 -6
- package/THIRD_PARTY_NOTICES.md +4 -0
- package/bin/aug.mjs +12 -2
- package/docs/about.md +27 -0
- package/docs/api/crypto.md +103 -69
- package/docs/api/io.md +35 -33
- package/docs/api/json.md +3 -3
- package/docs/api/memory.md +23 -19
- package/docs/api/time.md +10 -9
- package/docs/api/web.md +33 -38
- package/docs/compatibility.md +3 -3
- package/docs/contributing-benchmarks.md +38 -0
- package/docs/dev-containers.md +95 -0
- package/docs/diagnostics.md +15 -5
- package/docs/docker.md +174 -12
- package/docs/editor.md +35 -0
- package/docs/example-projects.json +206 -24
- package/docs/examples/approved-design/counters.md +34 -126
- package/docs/examples/approved-design/dependencies/august/0.20.1/io/contracts.md +178 -0
- package/docs/examples/approved-design/domain/app.md +13 -77
- package/docs/examples/approved-design/domain/export.md +5 -19
- package/docs/examples/approved-design/domain/models.md +4 -23
- package/docs/examples/approved-design/domain/numbers.md +24 -114
- package/docs/examples/approved-design/index.md +16 -7
- package/docs/examples/approved-design/main.md +19 -96
- package/docs/examples/benchmark/index.md +6 -5
- package/docs/examples/benchmark/main.md +7 -35
- package/docs/examples/cli-args/index.md +6 -5
- package/docs/examples/cli-args/main.md +6 -31
- package/docs/examples/collections/index.md +6 -5
- package/docs/examples/collections/main.md +7 -35
- package/docs/examples/collections-benchmark/index.md +6 -5
- package/docs/examples/collections-benchmark/main.md +7 -35
- package/docs/examples/cpu-benchmark/index.md +6 -5
- package/docs/examples/cpu-benchmark/main.md +5 -24
- package/docs/examples/developer-workflow/calculator.md +39 -186
- package/docs/examples/developer-workflow/dependencies/august/0.20.1/io/contracts.md +178 -0
- package/docs/examples/developer-workflow/index.md +16 -7
- package/docs/examples/developer-workflow/logging/console.md +10 -56
- package/docs/examples/developer-workflow/logging/export.md +4 -14
- package/docs/examples/developer-workflow/logging/logger.md +7 -43
- package/docs/examples/developer-workflow/main.md +17 -69
- package/docs/examples/drop/index.md +6 -5
- package/docs/examples/drop/main.md +7 -27
- package/docs/examples/drop/resource.md +7 -30
- package/docs/examples/errors/errors.md +7 -27
- package/docs/examples/errors/index.md +6 -5
- package/docs/examples/errors/main.md +7 -28
- package/docs/examples/ffi/index.md +6 -5
- package/docs/examples/ffi/main.md +6 -20
- package/docs/examples/ffi/native.md +8 -34
- package/docs/examples/generic-di/dependencies/august/0.20.1/io/contracts.md +178 -0
- package/docs/examples/generic-di/index.md +6 -5
- package/docs/examples/generic-di/main.md +9 -39
- package/docs/examples/generic-di/types.md +23 -92
- package/docs/examples/generics/index.md +6 -5
- package/docs/examples/generics/main.md +10 -47
- package/docs/examples/generics/types.md +25 -100
- package/docs/examples/hello/app/export.md +4 -12
- package/docs/examples/hello/app/greeter.md +13 -91
- package/docs/examples/hello/dependencies/august/0.20.1/io/contracts.md +178 -0
- package/docs/examples/hello/index.md +17 -6
- package/docs/examples/hello/logging/console.md +10 -54
- package/docs/examples/hello/logging/export.md +4 -14
- package/docs/examples/hello/logging/logger.md +7 -45
- package/docs/examples/hello/main.md +9 -39
- package/docs/examples/http-benchmark/index.md +6 -5
- package/docs/examples/http-benchmark/main.md +6 -20
- package/docs/examples/http-benchmark/routes.md +9 -31
- package/docs/examples/index.md +46 -29
- package/docs/examples/interceptors/app.md +20 -139
- package/docs/examples/interceptors/dependencies/august/0.20.1/io/contracts.md +178 -0
- package/docs/examples/interceptors/index.md +6 -5
- package/docs/examples/interceptors/interceptors.md +24 -148
- package/docs/examples/interceptors/logging.md +13 -76
- package/docs/examples/interceptors/main.md +10 -65
- package/docs/examples/json-benchmark/data.md +4 -20
- package/docs/examples/json-benchmark/dependencies/packages/@git/url_2d3c37c690c0fa115be1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.md +67 -0
- package/docs/examples/json-benchmark/index.md +7 -5
- package/docs/examples/json-benchmark/main-yaml.md +20 -0
- package/docs/examples/json-benchmark/main.md +10 -49
- package/docs/examples/new-syntax/console.md +10 -52
- package/docs/examples/new-syntax/dependencies/august/0.20.1/io/contracts.md +178 -0
- package/docs/examples/new-syntax/greeter.md +13 -71
- package/docs/examples/new-syntax/index.md +6 -5
- package/docs/examples/new-syntax/logger.md +7 -43
- package/docs/examples/new-syntax/main.md +10 -53
- package/docs/examples/new-syntax/math.md +6 -24
- package/docs/examples/oidc-login/client/contracts.md +10 -61
- package/docs/examples/oidc-login/client/endpoints.md +32 -154
- package/docs/examples/oidc-login/client/export.md +5 -23
- package/docs/examples/oidc-login/client/login.md +234 -344
- package/docs/examples/oidc-login/client/logout.md +38 -143
- package/docs/examples/oidc-login/client/protocol.md +183 -304
- package/docs/examples/oidc-login/client/session.md +41 -149
- package/docs/examples/oidc-login/client/views.md +13 -58
- package/docs/examples/oidc-login/common/export.md +6 -26
- package/docs/examples/oidc-login/common/headers.md +42 -72
- package/docs/examples/oidc-login/common/keys.md +40 -164
- package/docs/examples/oidc-login/common/settings.md +24 -40
- package/docs/examples/oidc-login/common/views.md +7 -28
- package/docs/examples/oidc-login/dependencies/packages/@git/url_0eb7c89453c87681ed15/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/store.md +205 -0
- package/docs/examples/oidc-login/dependencies/packages/@git/url_2d3c37c690c0fa115be1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.md +67 -0
- package/docs/examples/oidc-login/dependencies/packages/@git/url_897efafd565158fc4908/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.md +267 -0
- package/docs/examples/oidc-login/dependencies/packages/@git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/contracts.md +415 -0
- package/docs/examples/oidc-login/dependencies/packages/@git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/jose.md +271 -0
- package/docs/examples/oidc-login/dependencies/packages/@git/url_c092cd151499c4e1d8a1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.md +89 -0
- package/docs/examples/oidc-login/index.md +8 -7
- package/docs/examples/oidc-login/main-yaml.md +7 -0
- package/docs/examples/oidc-login/main.md +26 -153
- package/docs/examples/oidc-login/provider/authorization.md +232 -275
- package/docs/examples/oidc-login/provider/contracts.md +24 -146
- package/docs/examples/oidc-login/provider/credentials.md +24 -57
- package/docs/examples/oidc-login/provider/discovery.md +48 -122
- package/docs/examples/oidc-login/provider/export.md +11 -37
- package/docs/examples/oidc-login/provider/token.md +159 -237
- package/docs/examples/oidc-login/provider/userinfo.md +47 -102
- package/docs/examples/oidc-login/provider/views.md +13 -53
- package/docs/examples/ownership/counter.md +17 -63
- package/docs/examples/ownership/index.md +6 -5
- package/docs/examples/ownership/main.md +7 -30
- package/docs/examples/ownership-transfer/dependencies/august/0.20.1/io/contracts.md +178 -0
- package/docs/examples/ownership-transfer/index.md +6 -5
- package/docs/examples/ownership-transfer/main.md +10 -52
- package/docs/examples/ownership-transfer/resource.md +15 -67
- package/docs/examples/packages-app/dependencies/packages/@example/aug-math/0.1.0/arithmetic.md +12 -50
- package/docs/examples/packages-app/index.md +7 -6
- package/docs/examples/packages-app/main.md +7 -25
- package/docs/examples/packages-math/aug-package-json.md +1 -1
- package/docs/examples/packages-math/index.md +7 -6
- package/docs/examples/packages-math/src/arithmetic.md +12 -50
- package/docs/examples/packages-math/src/export.md +4 -12
- package/docs/examples/startup-benchmark/index.md +6 -5
- package/docs/examples/startup-benchmark/main.md +5 -17
- package/docs/examples/visibility/counter.md +19 -67
- package/docs/examples/visibility/index.md +6 -5
- package/docs/examples/visibility/main.md +7 -31
- package/docs/examples/weather-api/forecasts.md +168 -0
- package/docs/examples/weather-api/index.md +42 -0
- package/docs/examples/weather-api/main-yaml.md +21 -0
- package/docs/examples/weather-api/main.md +65 -0
- package/docs/examples.json +10 -0
- package/docs/getting-started.md +105 -2
- package/docs/grammar.md +6 -4
- package/docs/guides/change-a-module.md +64 -0
- package/docs/guides/index.md +27 -0
- package/docs/index.md +51 -29
- package/docs/language-conformance.md +1 -1
- package/docs/language-constructs.md +22 -22
- package/docs/language-design-audit.md +1 -1
- package/docs/learn/data-and-errors.md +77 -0
- package/docs/learn/index.md +30 -0
- package/docs/learn/modules-and-dependencies.md +73 -0
- package/docs/learn/state-and-tests.md +71 -0
- package/docs/learn/values-and-functions.md +62 -0
- package/docs/lesson-failures.json +8 -0
- package/docs/maintaining-docs.md +16 -4
- package/docs/packages.md +72 -126
- package/docs/performance.md +13 -41
- package/docs/production-readiness.md +5 -4
- package/docs/public/downloads/approved-design.zip +0 -0
- package/docs/public/downloads/benchmark.zip +0 -0
- package/docs/public/downloads/cli-args.zip +0 -0
- package/docs/public/downloads/collections-benchmark.zip +0 -0
- package/docs/public/downloads/collections.zip +0 -0
- package/docs/public/downloads/cpu-benchmark.zip +0 -0
- package/docs/public/downloads/developer-workflow.zip +0 -0
- package/docs/public/downloads/drop.zip +0 -0
- package/docs/public/downloads/errors.zip +0 -0
- package/docs/public/downloads/ffi.zip +0 -0
- package/docs/public/downloads/generic-di.zip +0 -0
- package/docs/public/downloads/generics.zip +0 -0
- package/docs/public/downloads/hello.zip +0 -0
- package/docs/public/downloads/http-benchmark.zip +0 -0
- package/docs/public/downloads/interceptors.zip +0 -0
- package/docs/public/downloads/json-benchmark.zip +0 -0
- package/docs/public/downloads/new-syntax.zip +0 -0
- package/docs/public/downloads/oidc-login.zip +0 -0
- package/docs/public/downloads/ownership-transfer.zip +0 -0
- package/docs/public/downloads/ownership.zip +0 -0
- package/docs/public/downloads/packages-app.zip +0 -0
- package/docs/public/downloads/packages-math.zip +0 -0
- package/docs/public/downloads/startup-benchmark.zip +0 -0
- package/docs/public/downloads/visibility.zip +0 -0
- package/docs/public/downloads/weather-api.zip +0 -0
- package/docs/reference.md +23 -17
- package/docs/releasing.md +29 -15
- package/docs/research/code-to-natural-language.md +108 -0
- package/docs/research/ecosystem-workflow.md +41 -0
- package/docs/research/wiki-editorial-design.md +71 -0
- package/docs/roadmap.md +1 -1
- package/docs/specifications.md +27 -11
- package/docs/testing.md +19 -5
- package/docs/tooling.md +25 -12
- package/docs/weather-api.md +65 -0
- package/docs/web.md +50 -18
- package/docs/writing-docs.md +49 -0
- package/examples/{hello/.aug-spec/august/0.19.0 → approved-design/.aug-spec/august/0.20.1}/io/contracts.aug +4 -3
- package/examples/approved-design/.aug-spec/august/0.20.1/io/contracts.aug.md +82 -0
- package/examples/approved-design/.aug-spec/manifest.json +3 -3
- package/examples/approved-design/counters.aug +5 -4
- package/examples/approved-design/counters.aug.md +25 -132
- package/examples/approved-design/domain/app.aug +2 -1
- package/examples/approved-design/domain/app.aug.md +10 -80
- package/examples/approved-design/domain/export.aug +1 -0
- package/examples/approved-design/domain/export.aug.md +4 -20
- package/examples/approved-design/domain/models.aug +1 -0
- package/examples/approved-design/domain/models.aug.md +3 -25
- package/examples/approved-design/domain/numbers.aug +3 -2
- package/examples/approved-design/domain/numbers.aug.md +19 -116
- package/examples/approved-design/main.aug +1 -0
- package/examples/approved-design/main.aug.md +12 -95
- package/examples/benchmark/.aug-spec/manifest.json +1 -1
- package/examples/benchmark/main.aug +1 -0
- package/examples/benchmark/main.aug.md +6 -36
- package/examples/cli-args/.aug-spec/manifest.json +1 -1
- package/examples/cli-args/main.aug +1 -0
- package/examples/cli-args/main.aug.md +5 -32
- package/examples/collections/.aug-spec/manifest.json +1 -1
- package/examples/collections/main.aug +1 -0
- package/examples/collections/main.aug.md +6 -36
- package/examples/{generic-di/.aug-spec/august/0.19.0 → developer-workflow/.aug-spec/august/0.20.1}/io/contracts.aug +4 -3
- package/examples/developer-workflow/.aug-spec/august/0.20.1/io/contracts.aug.md +82 -0
- package/examples/developer-workflow/.aug-spec/manifest.json +3 -3
- package/examples/developer-workflow/calculator.aug +3 -2
- package/examples/developer-workflow/calculator.aug.md +28 -189
- package/examples/developer-workflow/logging/console.aug +2 -1
- package/examples/developer-workflow/logging/console.aug.md +7 -57
- package/examples/developer-workflow/logging/export.aug +1 -0
- package/examples/developer-workflow/logging/export.aug.md +3 -15
- package/examples/developer-workflow/logging/logger.aug +1 -0
- package/examples/developer-workflow/logging/logger.aug.md +6 -46
- package/examples/developer-workflow/main.aug +1 -0
- package/examples/developer-workflow/main.aug.md +10 -68
- package/examples/drop/.aug-spec/manifest.json +1 -1
- package/examples/drop/main.aug +1 -0
- package/examples/drop/main.aug.md +6 -28
- package/examples/drop/resource.aug +1 -0
- package/examples/drop/resource.aug.md +6 -34
- package/examples/errors/.aug-spec/manifest.json +1 -1
- package/examples/errors/errors.aug +2 -1
- package/examples/errors/errors.aug.md +4 -27
- package/examples/errors/main.aug +1 -0
- package/examples/errors/main.aug.md +6 -29
- package/examples/ffi/.aug-spec/manifest.json +1 -1
- package/examples/ffi/main.aug +1 -0
- package/examples/ffi/main.aug.md +5 -21
- package/examples/ffi/native.aug +2 -1
- package/examples/ffi/native.aug.md +5 -35
- package/examples/{approved-design/.aug-spec/august/0.19.0 → generic-di/.aug-spec/august/0.20.1}/io/contracts.aug +4 -3
- package/examples/generic-di/.aug-spec/august/0.20.1/io/contracts.aug.md +82 -0
- package/examples/generic-di/.aug-spec/manifest.json +3 -3
- package/examples/generic-di/main.aug +1 -0
- package/examples/generic-di/main.aug.md +8 -40
- package/examples/generic-di/types.aug +3 -2
- package/examples/generic-di/types.aug.md +18 -97
- package/examples/generics/.aug-spec/manifest.json +1 -1
- package/examples/generics/main.aug +1 -0
- package/examples/generics/main.aug.md +9 -48
- package/examples/generics/types.aug +4 -3
- package/examples/generics/types.aug.md +18 -104
- package/examples/{developer-workflow/.aug-spec/august/0.19.0 → hello/.aug-spec/august/0.20.1}/io/contracts.aug +4 -3
- package/examples/hello/.aug-spec/august/0.20.1/io/contracts.aug.md +82 -0
- package/examples/hello/.aug-spec/manifest.json +3 -3
- package/examples/hello/app/export.aug +1 -0
- package/examples/hello/app/export.aug.md +3 -13
- package/examples/hello/app/greeter.aug +2 -1
- package/examples/hello/app/greeter.aug.md +10 -94
- package/examples/hello/logging/console.aug +2 -1
- package/examples/hello/logging/console.aug.md +7 -55
- package/examples/hello/logging/export.aug +1 -0
- package/examples/hello/logging/export.aug.md +3 -15
- package/examples/hello/logging/logger.aug +1 -0
- package/examples/hello/logging/logger.aug.md +6 -48
- package/examples/hello/main.aug +1 -0
- package/examples/hello/main.aug.md +8 -40
- package/examples/interceptors/.aug-spec/august/0.20.1/io/contracts.aug +37 -0
- package/examples/interceptors/.aug-spec/august/0.20.1/io/contracts.aug.md +82 -0
- package/examples/interceptors/.aug-spec/manifest.json +3 -3
- package/examples/interceptors/app.aug +3 -2
- package/examples/interceptors/app.aug.md +15 -141
- package/examples/interceptors/interceptors.aug +3 -2
- package/examples/interceptors/interceptors.aug.md +19 -152
- package/examples/interceptors/logging.aug +2 -1
- package/examples/interceptors/logging.aug.md +10 -79
- package/examples/interceptors/main.aug +1 -0
- package/examples/interceptors/main.aug.md +9 -66
- package/examples/new-syntax/.aug-spec/august/0.20.1/io/contracts.aug +37 -0
- package/examples/new-syntax/.aug-spec/august/0.20.1/io/contracts.aug.md +82 -0
- package/examples/new-syntax/.aug-spec/manifest.json +3 -3
- package/examples/new-syntax/console.aug +2 -1
- package/examples/new-syntax/console.aug.md +7 -53
- package/examples/new-syntax/greeter.aug +2 -1
- package/examples/new-syntax/greeter.aug.md +10 -74
- package/examples/new-syntax/logger.aug +1 -0
- package/examples/new-syntax/logger.aug.md +6 -46
- package/examples/new-syntax/main.aug +1 -0
- package/examples/new-syntax/main.aug.md +9 -54
- package/examples/new-syntax/math.aug +2 -1
- package/examples/new-syntax/math.aug.md +3 -24
- package/examples/oidc-login/.aug-spec/manifest.json +13 -13
- package/examples/oidc-login/.aug-spec/packages/@git/url_0eb7c89453c87681ed15/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/store.aug.md +71 -0
- package/examples/oidc-login/.aug-spec/packages/@git/url_2d3c37c690c0fa115be1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.aug.md +17 -0
- package/examples/oidc-login/.aug-spec/packages/@git/url_897efafd565158fc4908/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.aug.md +125 -0
- package/examples/oidc-login/.aug-spec/{august/0.19.0/crypto → packages/@git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40}/contracts.aug +12 -11
- package/examples/oidc-login/.aug-spec/packages/@git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/contracts.aug.md +244 -0
- package/examples/oidc-login/.aug-spec/{august/0.19.0/crypto → packages/@git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40}/jose.aug +6 -5
- package/examples/oidc-login/.aug-spec/packages/@git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/jose.aug.md +71 -0
- package/examples/oidc-login/.aug-spec/packages/@git/url_c092cd151499c4e1d8a1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.aug.md +30 -0
- package/examples/oidc-login/aug.lock.json +100 -0
- package/examples/oidc-login/client/contracts.aug +1 -0
- package/examples/oidc-login/client/contracts.aug.md +9 -66
- package/examples/oidc-login/client/endpoints.aug +6 -5
- package/examples/oidc-login/client/endpoints.aug.md +13 -145
- package/examples/oidc-login/client/export.aug +1 -0
- package/examples/oidc-login/client/export.aug.md +4 -24
- package/examples/oidc-login/client/login.aug +7 -6
- package/examples/oidc-login/client/login.aug.md +25 -303
- package/examples/oidc-login/client/logout.aug +5 -4
- package/examples/oidc-login/client/logout.aug.md +13 -135
- package/examples/oidc-login/client/protocol.aug +7 -6
- package/examples/oidc-login/client/protocol.aug.md +36 -283
- package/examples/oidc-login/client/session.aug +5 -4
- package/examples/oidc-login/client/session.aug.md +12 -139
- package/examples/oidc-login/client/views.aug +3 -2
- package/examples/oidc-login/client/views.aug.md +8 -57
- package/examples/oidc-login/common/export.aug +1 -0
- package/examples/oidc-login/common/export.aug.md +5 -27
- package/examples/oidc-login/common/headers.aug +4 -3
- package/examples/oidc-login/common/headers.aug.md +9 -67
- package/examples/oidc-login/common/keys.aug +6 -5
- package/examples/oidc-login/common/keys.aug.md +29 -165
- package/examples/oidc-login/common/settings.aug +2 -1
- package/examples/oidc-login/common/settings.aug.md +5 -39
- package/examples/oidc-login/common/views.aug +2 -1
- package/examples/oidc-login/common/views.aug.md +4 -28
- package/examples/oidc-login/main.aug +6 -16
- package/examples/oidc-login/main.aug.md +17 -146
- package/examples/oidc-login/main.yaml +7 -0
- package/examples/oidc-login/provider/authorization.aug +7 -6
- package/examples/oidc-login/provider/authorization.aug.md +23 -238
- package/examples/oidc-login/provider/contracts.aug +1 -0
- package/examples/oidc-login/provider/contracts.aug.md +23 -158
- package/examples/oidc-login/provider/credentials.aug +3 -2
- package/examples/oidc-login/provider/credentials.aug.md +9 -53
- package/examples/oidc-login/provider/discovery.aug +4 -3
- package/examples/oidc-login/provider/discovery.aug.md +11 -118
- package/examples/oidc-login/provider/export.aug +1 -0
- package/examples/oidc-login/provider/export.aug.md +6 -34
- package/examples/oidc-login/provider/token.aug +6 -5
- package/examples/oidc-login/provider/token.aug.md +16 -204
- package/examples/oidc-login/provider/userinfo.aug +4 -3
- package/examples/oidc-login/provider/userinfo.aug.md +10 -92
- package/examples/oidc-login/provider/views.aug +3 -2
- package/examples/oidc-login/provider/views.aug.md +8 -52
- package/examples/ownership/.aug-spec/manifest.json +1 -1
- package/examples/ownership/counter.aug +3 -2
- package/examples/ownership/counter.aug.md +12 -66
- package/examples/ownership/main.aug +1 -0
- package/examples/ownership/main.aug.md +6 -31
- package/examples/ownership-transfer/.aug-spec/august/0.20.1/io/contracts.aug +37 -0
- package/examples/ownership-transfer/.aug-spec/august/0.20.1/io/contracts.aug.md +82 -0
- package/examples/ownership-transfer/.aug-spec/manifest.json +3 -3
- package/examples/ownership-transfer/main.aug +1 -0
- package/examples/ownership-transfer/main.aug.md +9 -53
- package/examples/ownership-transfer/resource.aug +2 -1
- package/examples/ownership-transfer/resource.aug.md +12 -71
- package/examples/packages/app/.aug-spec/manifest.json +1 -1
- package/examples/packages/app/.aug-spec/packages/@example/aug-math/0.1.0/arithmetic.aug +2 -1
- package/examples/packages/app/.aug-spec/packages/@example/aug-math/0.1.0/arithmetic.aug.md +9 -51
- package/examples/packages/app/main.aug +1 -0
- package/examples/packages/app/main.aug.md +6 -26
- package/examples/packages/math/.aug-spec/manifest.json +1 -1
- package/examples/packages/math/aug-package.json +1 -1
- package/examples/packages/math/src/arithmetic.aug +2 -1
- package/examples/packages/math/src/arithmetic.aug.md +9 -51
- package/examples/packages/math/src/export.aug +1 -0
- package/examples/packages/math/src/export.aug.md +3 -13
- package/examples/visibility/.aug-spec/manifest.json +1 -1
- package/examples/visibility/counter.aug +4 -3
- package/examples/visibility/counter.aug.md +12 -68
- package/examples/visibility/main.aug +1 -0
- package/examples/visibility/main.aug.md +6 -32
- package/examples/weather-api/.aug-spec/manifest.json +8 -0
- package/examples/weather-api/AGENTS.md +17 -0
- package/examples/weather-api/README.md +19 -0
- package/examples/weather-api/forecasts.aug +47 -0
- package/examples/weather-api/forecasts.aug.md +32 -0
- package/examples/weather-api/main.aug +4 -0
- package/examples/weather-api/main.aug.md +15 -0
- package/examples/weather-api/main.yaml +5 -0
- package/examples/weather-api/weather.http +5 -0
- package/package.json +3 -4
- package/scripts/bootstrap-native.mjs +181 -106
- package/scripts/native-setup.mjs +98 -0
- package/scripts/native-toolchain.mjs +28 -0
- package/src/builtins.js +1 -1
- package/src/checker.js +259 -72
- package/src/cli.js +114 -20
- package/src/codegen.js +1 -1
- package/src/config.js +1 -1
- package/src/contracts.js +10 -0
- package/src/editor.js +71 -16
- package/src/fixes.js +90 -2
- package/src/formatter.js +19 -8
- package/src/git-packages.js +110 -0
- package/src/help.js +24 -23
- package/src/http-contracts.js +14 -0
- package/src/http-policies.js +5 -5
- package/src/libraries.js +1 -1
- package/src/lsp.js +14 -5
- package/src/native.js +19 -13
- package/src/navigation.js +4 -2
- package/src/openapi.js +5 -4
- package/src/package-locking.js +45 -0
- package/src/package-manager.js +251 -67
- package/src/parser.js +13 -5
- package/src/policies.js +3 -3
- package/src/project-init.js +78 -4
- package/src/project.js +9 -7
- package/src/semantic.js +46 -2
- package/src/snippets.js +59 -0
- package/src/spec-hints.js +56 -0
- package/src/spec-tree.js +241 -0
- package/src/spec.js +626 -303
- package/docs/examples/approved-design/dependencies/august/0.19.0/io/contracts.md +0 -395
- package/docs/examples/developer-workflow/dependencies/august/0.19.0/io/contracts.md +0 -395
- package/docs/examples/generic-di/dependencies/august/0.19.0/io/contracts.md +0 -395
- package/docs/examples/hello/dependencies/august/0.19.0/io/contracts.md +0 -395
- package/docs/examples/interceptors/dependencies/august/0.19.0/io/contracts.md +0 -395
- package/docs/examples/json-benchmark/dependencies/august/0.19.0/json/contracts.md +0 -103
- package/docs/examples/new-syntax/dependencies/august/0.19.0/io/contracts.md +0 -395
- package/docs/examples/oidc-login/dependencies/august/0.19.0/crypto/contracts.md +0 -925
- package/docs/examples/oidc-login/dependencies/august/0.19.0/crypto/jose.md +0 -434
- package/docs/examples/oidc-login/dependencies/august/0.19.0/json/contracts.md +0 -103
- package/docs/examples/oidc-login/dependencies/august/0.19.0/memory/store.md +0 -374
- package/docs/examples/oidc-login/dependencies/august/0.19.0/time/contracts.md +0 -150
- package/docs/examples/oidc-login/dependencies/august/0.19.0/web/contracts.md +0 -532
- package/docs/examples/ownership-transfer/dependencies/august/0.19.0/io/contracts.md +0 -395
- package/examples/approved-design/.aug-spec/august/0.19.0/io/contracts.aug.md +0 -316
- package/examples/developer-workflow/.aug-spec/august/0.19.0/io/contracts.aug.md +0 -316
- package/examples/generic-di/.aug-spec/august/0.19.0/io/contracts.aug.md +0 -316
- package/examples/hello/.aug-spec/august/0.19.0/io/contracts.aug.md +0 -316
- package/examples/interceptors/.aug-spec/august/0.19.0/io/contracts.aug +0 -36
- package/examples/interceptors/.aug-spec/august/0.19.0/io/contracts.aug.md +0 -316
- package/examples/new-syntax/.aug-spec/august/0.19.0/io/contracts.aug +0 -36
- package/examples/new-syntax/.aug-spec/august/0.19.0/io/contracts.aug.md +0 -316
- package/examples/oidc-login/.aug-spec/august/0.19.0/crypto/contracts.aug.md +0 -791
- package/examples/oidc-login/.aug-spec/august/0.19.0/crypto/jose.aug.md +0 -266
- package/examples/oidc-login/.aug-spec/august/0.19.0/json/contracts.aug.md +0 -55
- package/examples/oidc-login/.aug-spec/august/0.19.0/memory/store.aug.md +0 -250
- package/examples/oidc-login/.aug-spec/august/0.19.0/time/contracts.aug.md +0 -96
- package/examples/oidc-login/.aug-spec/august/0.19.0/web/contracts.aug.md +0 -420
- package/examples/ownership-transfer/.aug-spec/august/0.19.0/io/contracts.aug +0 -36
- package/examples/ownership-transfer/.aug-spec/august/0.19.0/io/contracts.aug.md +0 -316
- /package/examples/oidc-login/.aug-spec/{august/0.19.0/memory → packages/@git/url_0eb7c89453c87681ed15/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301}/store.aug +0 -0
- /package/examples/oidc-login/.aug-spec/{august/0.19.0/json → packages/@git/url_2d3c37c690c0fa115be1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301}/contracts.aug +0 -0
- /package/examples/oidc-login/.aug-spec/{august/0.19.0/web → packages/@git/url_897efafd565158fc4908/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301}/contracts.aug +0 -0
- /package/examples/oidc-login/.aug-spec/{august/0.19.0/time → packages/@git/url_c092cd151499c4e1d8a1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301}/contracts.aug +0 -0
|
@@ -1,14 +1,15 @@
|
|
|
1
|
+
// aug-spec: "authorization.aug.md" explains this file. Read it before changes; refresh with aug spec.
|
|
1
2
|
import AuthorizationRequest and AuthorizationCode and LoginForm and LoginError from contracts
|
|
2
3
|
import ProviderLogin and ProviderFailure from views
|
|
3
4
|
import verifyCredentials from credentials
|
|
4
5
|
import settings and securityHeaders and withCookie from common
|
|
5
|
-
import Crypto from
|
|
6
|
-
import Clock from
|
|
7
|
-
import ExpiringStore and StoreFull from
|
|
8
|
-
import urlEncode from
|
|
6
|
+
import Crypto from crypto
|
|
7
|
+
import Clock from time
|
|
8
|
+
import ExpiringStore and StoreFull from memory
|
|
9
|
+
import urlEncode from web
|
|
9
10
|
|
|
10
11
|
/** Validate the registered client before offering a login form. A malformed redirect is never followed. */
|
|
11
|
-
endpoint GET "/provider/authorize" as authorize(string response_type from query, string client_id from query, string redirect_uri from query, string requestedScope from query "scope", string state from query, string nonce from query, string code_challenge from query, string code_challenge_method from query, resolve Crypto crypto, resolve Clock clock, resolve ExpiringStore<AuthorizationRequest> requests)
|
|
12
|
+
endpoint GET "/provider/authorize" as authorize(string response_type from query, string client_id from query, string redirect_uri from query, string requestedScope from query "scope", string state from query, string nonce from query, string code_challenge from query, string code_challenge_method from query, resolve Crypto crypto, resolve Clock clock, resolve ExpiringStore<AuthorizationRequest> requests) unless LoginError with status 400 and CryptoError with status 503 and TimeError with status 503 and StoreFull with status 503 and HttpError:
|
|
12
13
|
config = settings()
|
|
13
14
|
if client_id != config.clientId or redirect_uri != config.callback or response_type != "code" or code_challenge_method != "S256":
|
|
14
15
|
throw LoginError()
|
|
@@ -31,7 +32,7 @@ endpoint GET "/provider/authorize" as authorize(string response_type from query,
|
|
|
31
32
|
return HttpResponse(body=ProviderLogin(requestId, csrf, message="Authorize the registered August login app.", submit=handle providerLogin(input from form)), headers=headers)
|
|
32
33
|
|
|
33
34
|
/** The browser binding and CSRF token are checked before credentials. Each form request is consumed once. */
|
|
34
|
-
endpoint POST "/provider/login" as providerLogin(LoginForm form from form, optional string browser from cookie "aug_authorize", optional string origin from header "origin", resolve Crypto crypto, resolve Clock clock, resolve ExpiringStore<AuthorizationRequest> requests, resolve ExpiringStore<AuthorizationCode> codes)
|
|
35
|
+
endpoint POST "/provider/login" as providerLogin(LoginForm form from form, optional string browser from cookie "aug_authorize", optional string origin from header "origin", resolve Crypto crypto, resolve Clock clock, resolve ExpiringStore<AuthorizationRequest> requests, resolve ExpiringStore<AuthorizationCode> codes) unless CryptoError with status 503 and TimeError with status 503 and StoreFull with status 503 and HttpError:
|
|
35
36
|
config = settings()
|
|
36
37
|
try:
|
|
37
38
|
if origin != config.baseUrl:
|
|
@@ -1,264 +1,49 @@
|
|
|
1
1
|
<!-- Generated by aug spec. Edit the August source, then regenerate. -->
|
|
2
2
|
|
|
3
|
-
# `authorization.aug`
|
|
3
|
+
# `authorization.aug`
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
## In this file
|
|
8
|
-
|
|
9
|
-
- [`authorize`](authorization.aug.md#symbol-authorize) handles `GET` `/provider/authorize` returning `HttpResponse<Html>`.
|
|
10
|
-
- [`providerLogin`](authorization.aug.md#symbol-providerLogin) handles `POST` `/provider/login` returning `HttpResponse<Html>`.
|
|
5
|
+
Plain handler results default to HTTP 200 unless another status is declared. HttpResponse values choose their own status. Unhandled request failures return HTTP 500 and cancel the request tasks.
|
|
11
6
|
|
|
12
7
|
<a id="symbol-authorize"></a>
|
|
8
|
+
## `authorize` · [source](authorization.aug#L12)
|
|
13
9
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
[source](authorization.aug#L11)
|
|
17
|
-
|
|
18
|
-
**Inputs**
|
|
19
|
-
|
|
20
|
-
- `response_type` (`string`) — read from the HTTP query.
|
|
21
|
-
- `client_id` (`string`) — read from the HTTP query.
|
|
22
|
-
- `redirect_uri` (`string`) — read from the HTTP query.
|
|
23
|
-
- `requestedScope` (`string`) — read from the HTTP query named `scope`.
|
|
24
|
-
- `state` (`string`) — read from the HTTP query.
|
|
25
|
-
- `nonce` (`string`) — read from the HTTP query.
|
|
26
|
-
- `code_challenge` (`string`) — read from the HTTP query.
|
|
27
|
-
- `code_challenge_method` (`string`) — read from the HTTP query.
|
|
28
|
-
- `crypto` ([`Crypto`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto)) — injected; callers omit it.
|
|
29
|
-
- `clock` ([`Clock`](../.aug-spec/august/0.19.0/time/contracts.aug.md#symbol-Clock)) — injected; callers omit it.
|
|
30
|
-
- `requests` ([`ExpiringStore<AuthorizationRequest>`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-ExpiringStore)) — injected; callers omit it.
|
|
31
|
-
|
|
32
|
-
Returns: `HttpResponse<Html>`.
|
|
33
|
-
|
|
34
|
-
Capabilities: [`crypto.random`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.random), [`crypto.decodeBase64url`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.decodeBase64url), [`clock.now`](../.aug-spec/august/0.19.0/time/contracts.aug.md#symbol-Clock.now), [`requests.put`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-ExpiringStore.put).
|
|
35
|
-
|
|
36
|
-
Can fail with `LoginError`, `CryptoError`, `TimeError`, `StoreFull`, `HttpError`. Callers must catch or propagate these errors.
|
|
10
|
+
`authorize` handles `GET /provider/authorize`. Validate the registered client before offering a login form. A malformed redirect is never followed.
|
|
37
11
|
|
|
38
|
-
|
|
12
|
+
It reads `response_type`, `client_id`, `redirect_uri`, `scope`, `state`, `nonce`, `code_challenge`, and `code_challenge_method` from the HTTP query. `scope` is called `requestedScope` here. It gets `crypto` ([`Crypto`](../.aug-spec/packages/%40git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/contracts.aug.md#symbol-Crypto)), `clock` ([`Clock`](../.aug-spec/packages/%40git/url_c092cd151499c4e1d8a1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.aug.md#symbol-Clock)), and `requests` ([`ExpiringStore<AuthorizationRequest>`](../.aug-spec/packages/%40git/url_0eb7c89453c87681ed15/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/store.aug.md#symbol-ExpiringStore)) from dependency injection. The handler responds with HTTP 400 for [`LoginError`](contracts.aug.md#symbol-LoginError), HTTP 503 for `CryptoError`, HTTP 503 for `TimeError`, and HTTP 503 for [`StoreFull`](../.aug-spec/packages/%40git/url_0eb7c89453c87681ed15/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/store.aug.md#symbol-StoreFull).
|
|
39
13
|
|
|
40
|
-
|
|
14
|
+
It can also raise `HttpError`. It gets `config` from [`settings`](../common/settings.aug.md#symbol-settings). It checks that `client_id` equals `config.clientId` and `redirect_uri` equals `config.callback` and `response_type` equals `"code"` and `code_challenge_method` equals `"S256"`, `requestedScope` is either `"openid"` or `"openid profile"`, and `state` is a URL-safe ASCII token with `43` to `128` characters and `nonce` is a URL-safe ASCII token with `43` to `128` characters and the byte length of `code_challenge` equals `43`. It raises a [`LoginError`](contracts.aug.md#symbol-LoginError) at the first failed check.
|
|
41
15
|
|
|
42
|
-
|
|
16
|
+
It checks that the byte length of [`crypto.decodeBase64url`](../.aug-spec/packages/%40git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/contracts.aug.md#symbol-Crypto.decodeBase64url) with `input` from `code_challenge` equals `32`. It raises a [`LoginError`](contracts.aug.md#symbol-LoginError) at the first failed check. If this work raises `CryptoError`, it raises a [`LoginError`](contracts.aug.md#symbol-LoginError). It sets `requestId`, `browser`, and `csrf` separately, each to the URL-safe base64 encoding of [`crypto.random`](../.aug-spec/packages/%40git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/contracts.aug.md#symbol-Crypto.random) with `size` `32`.
|
|
43
17
|
|
|
44
|
-
-
|
|
45
|
-
- If (((`client_id` does not equal `clientId` of `config`) or (`redirect_uri` does not equal `callback` of `config`)) or (`response_type` does not equal `"code"`)) or (`code_challenge_method` does not equal `"S256"`):
|
|
46
|
-
- Fail with call [`LoginError`](contracts.aug.md#symbol-LoginError). Transfer control to a matching catch or propagate the failure.
|
|
47
|
-
- If (`requestedScope` does not equal `"openid"`) and (`requestedScope` does not equal `"openid profile"`):
|
|
48
|
-
- Fail with call [`LoginError`](contracts.aug.md#symbol-LoginError). Transfer control to a matching catch or propagate the failure.
|
|
49
|
-
- If (not (call `isToken` on `state` with `min` = `43`; `max` = `128`) or not (call `isToken` on `nonce` with `min` = `43`; `max` = `128`)) or (call `length` on `code_challenge` does not equal `43`):
|
|
50
|
-
- Fail with call [`LoginError`](contracts.aug.md#symbol-LoginError). Transfer control to a matching catch or propagate the failure.
|
|
51
|
-
- Try these operations:
|
|
52
|
-
- If call `length` on call [`Crypto.decodeBase64url`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.decodeBase64url) on `crypto` with `input` = `code_challenge` does not equal `32`:
|
|
53
|
-
- Fail with call [`LoginError`](contracts.aug.md#symbol-LoginError). Transfer control to a matching catch or propagate the failure.
|
|
54
|
-
- If they fail with `CryptoError`, name the failure `error` and recover:
|
|
55
|
-
- Fail with call [`LoginError`](contracts.aug.md#symbol-LoginError). Transfer control to a matching catch or propagate the failure.
|
|
56
|
-
- Set `requestId` 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`.
|
|
57
|
-
- Set `browser` to call `base64url` on call [`Crypto.random`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.random) on `crypto` with `size` = `32`.
|
|
58
|
-
- Set `csrf` 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 `now` to call [`Clock.now`](../.aug-spec/august/0.19.0/time/contracts.aug.md#symbol-Clock.now) on `clock`.
|
|
60
|
-
- Set `request` to call [`AuthorizationRequest`](contracts.aug.md#symbol-AuthorizationRequest) with `clientId` = `client_id`; `redirectUri` = `redirect_uri`; `state` = `state`; `nonce` = `nonce`; `challenge` = `code_challenge`; `browser` = `browser`; `csrf` = `csrf`; `expires` = (`now` plus `300`).
|
|
61
|
-
- Call [`ExpiringStore.put`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-ExpiringStore.put) on `requests` with `key` = `requestId`; `value` = `request`; `expires` = `expires` of `request`; `now` = `now`.
|
|
62
|
-
- Set `headers` to call [`withCookie`](../common/headers.aug.md#symbol-withCookie) with `headers` = call [`securityHeaders`](../common/headers.aug.md#symbol-securityHeaders); `name` = `"aug_authorize"`; `value` = `browser`; `path` = `"/provider"`; `maxAge` = `300`; `secure` = `secureCookies` of `config`.
|
|
63
|
-
- Return call `HttpResponse` with `body` = call [`ProviderLogin`](views.aug.md#symbol-ProviderLogin) with `requestId` = `requestId`; `csrf` = `csrf`; `message` = `"Authorize the registered August login app."`; `submit` = a deferred HTTP form action for [`providerLogin`](authorization.aug.md#symbol-providerLogin); inputs: `1` from the checked form input supplied when the HTTP form is submitted; capture supplied values when rendering, and read form inputs when submitted; send the form to that endpoint with its declared HTTP method; `headers` = `headers`.
|
|
18
|
+
It sets `now` to [`clock.now`](../.aug-spec/packages/%40git/url_c092cd151499c4e1d8a1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.aug.md#symbol-Clock.now). It sets `request` to an [`AuthorizationRequest`](contracts.aug.md#symbol-AuthorizationRequest) with `clientId` from `client_id`, `redirectUri` from `redirect_uri`, `state`, `nonce`, `challenge` from `code_challenge`, `browser`, `csrf`, and `expires` from `now` plus `300`. It calls [`requests.put`](../.aug-spec/packages/%40git/url_0eb7c89453c87681ed15/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/store.aug.md#symbol-ExpiringStore.put) with `key` from `requestId`, `value` from `request`, `request.expires`, and `now`. It sets `headers` to [`withCookie`](../common/headers.aug.md#symbol-withCookie) with `headers` from [`securityHeaders`](../common/headers.aug.md#symbol-securityHeaders), `name` `"aug_authorize"`, `value` from `browser`, `path` `"/provider"`, `maxAge` `300`, and `secure` from `config.secureCookies`.
|
|
64
19
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
Validate the registered client before offering a login form. A malformed redirect is never followed.
|
|
20
|
+
It returns HTTP 200 with [`ProviderLogin`](views.aug.md#symbol-ProviderLogin) with `requestId`, `csrf`, `message` `"Authorize the registered August login app."`, and `submit` from a form action that sends `POST /provider/login` to [`providerLogin`](authorization.aug.md#symbol-providerLogin) on submission and `headers` headers.
|
|
68
21
|
|
|
69
22
|
<a id="symbol-providerLogin"></a>
|
|
23
|
+
## `providerLogin` · [source](authorization.aug#L35)
|
|
70
24
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
[source](authorization.aug#L34)
|
|
74
|
-
|
|
75
|
-
**Inputs**
|
|
76
|
-
|
|
77
|
-
- `form` ([`LoginForm`](contracts.aug.md#symbol-LoginForm)) — read from the HTTP form.
|
|
78
|
-
- `browser` (`optional string`) — read from the HTTP cookie named `aug_authorize`; absent value becomes null.
|
|
79
|
-
- `origin` (`optional string`) — read from the HTTP header named `origin`; absent value becomes null.
|
|
80
|
-
- `crypto` ([`Crypto`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto)) — injected; callers omit it.
|
|
81
|
-
- `clock` ([`Clock`](../.aug-spec/august/0.19.0/time/contracts.aug.md#symbol-Clock)) — injected; callers omit it.
|
|
82
|
-
- `requests` ([`ExpiringStore<AuthorizationRequest>`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-ExpiringStore)) — injected; callers omit it.
|
|
83
|
-
- `codes` ([`ExpiringStore<AuthorizationCode>`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-ExpiringStore)) — injected; callers omit it.
|
|
84
|
-
|
|
85
|
-
Returns: `HttpResponse<Html>`.
|
|
86
|
-
|
|
87
|
-
Capabilities: [`crypto.equal`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.equal), [`crypto.random`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.random), [`crypto.passwordHash`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.passwordHash), [`crypto.decodeBase64url`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.decodeBase64url), [`clock.now`](../.aug-spec/august/0.19.0/time/contracts.aug.md#symbol-Clock.now), [`requests.take`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-ExpiringStore.take), [`codes.put`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-ExpiringStore.put).
|
|
88
|
-
|
|
89
|
-
Can fail with `CryptoError`, `TimeError`, `StoreFull`, `HttpError`. Callers must catch or propagate these errors.
|
|
90
|
-
|
|
91
|
-
HTTP route: `POST` `/provider/login`. 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.
|
|
92
|
-
|
|
93
|
-
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.
|
|
94
|
-
|
|
95
|
-
**What it does**
|
|
96
|
-
|
|
97
|
-
- Set `config` to call [`settings`](../common/settings.aug.md#symbol-settings).
|
|
98
|
-
- Try these operations:
|
|
99
|
-
- If `origin` does not equal `baseUrl` of `config`:
|
|
100
|
-
- Return call `HttpResponse` with `body` = call [`ProviderFailure`](views.aug.md#symbol-ProviderFailure) with `message` = `"The sign-in form must come from this app."`; `status` = `403`; `headers` = call [`securityHeaders`](../common/headers.aug.md#symbol-securityHeaders).
|
|
101
|
-
- Select the matching case for call [`ExpiringStore.take`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-ExpiringStore.take) on `requests` with `key` = `request_id` of `form`; `now` = call [`Clock.now`](../.aug-spec/august/0.19.0/time/contracts.aug.md#symbol-Clock.now) on `clock`:
|
|
102
|
-
- A null value, including omitted optional input:
|
|
103
|
-
- Return call `HttpResponse` with `body` = call [`ProviderFailure`](views.aug.md#symbol-ProviderFailure) with `message` = `"The sign-in request expired or was already used."`; `status` = `400`; `headers` = call [`securityHeaders`](../common/headers.aug.md#symbol-securityHeaders).
|
|
104
|
-
- A present, non-null value, named `request`:
|
|
105
|
-
- Select the matching case for `browser`:
|
|
106
|
-
- A null value, including omitted optional input:
|
|
107
|
-
- Return call `HttpResponse` with `body` = call [`ProviderFailure`](views.aug.md#symbol-ProviderFailure) with `message` = `"The browser binding is missing."`; `status` = `403`; `headers` = call [`securityHeaders`](../common/headers.aug.md#symbol-securityHeaders).
|
|
108
|
-
- A present, non-null value, named `secret`:
|
|
109
|
-
- If not (call [`Crypto.equal`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.equal) on `crypto` with `left` = call `bytes` on `secret`; `right` = call `bytes` on `browser` of `request`) 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 `csrf` of `form`; `right` = call `bytes` on `csrf` of `request`):
|
|
110
|
-
- Return call `HttpResponse` with `body` = call [`ProviderFailure`](views.aug.md#symbol-ProviderFailure) with `message` = `"The sign-in form could not be verified."`; `status` = `403`; `headers` = call [`securityHeaders`](../common/headers.aug.md#symbol-securityHeaders).
|
|
111
|
-
- If not (call [`verifyCredentials`](credentials.aug.md#symbol-verifyCredentials) with `username` = `username` of `form`; `password` = `password` of `form`; inject `crypto` from `crypto`):
|
|
112
|
-
- Return call `HttpResponse` with `body` = call [`ProviderFailure`](views.aug.md#symbol-ProviderFailure) with `message` = `"The username or password was not accepted."`; `status` = `401`; `headers` = call [`securityHeaders`](../common/headers.aug.md#symbol-securityHeaders).
|
|
113
|
-
- Set `now` to call [`Clock.now`](../.aug-spec/august/0.19.0/time/contracts.aug.md#symbol-Clock.now) on `clock`.
|
|
114
|
-
- Set `code` 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`.
|
|
115
|
-
- Set `grant` to call [`AuthorizationCode`](contracts.aug.md#symbol-AuthorizationCode) with `clientId` = `clientId` of `request`; `redirectUri` = `redirectUri` of `request`; `challenge` = `challenge` of `request`; `nonce` = `nonce` of `request`; `subject` = `"demo-ada"`; `name` = `"Ada"`; `expires` = (`now` plus `60`).
|
|
116
|
-
- Call [`ExpiringStore.put`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-ExpiringStore.put) on `codes` with `key` = `code`; `value` = `grant`; `expires` = `expires` of `grant`; `now` = `now`.
|
|
117
|
-
- Build `location` by joining these text parts without separators, in order:
|
|
118
|
-
1. `redirectUri` of `request`
|
|
119
|
-
2. `"?code="`
|
|
120
|
-
3. call [`urlEncode`](../.aug-spec/august/0.19.0/web/contracts.aug.md#symbol-urlEncode) with `input` = `code`
|
|
121
|
-
4. `"&state="`
|
|
122
|
-
5. call [`urlEncode`](../.aug-spec/august/0.19.0/web/contracts.aug.md#symbol-urlEncode) with `input` = `state` of `request`
|
|
123
|
-
- Set `headers` to call [`withCookie`](../common/headers.aug.md#symbol-withCookie) with `headers` = call `with` on call [`securityHeaders`](../common/headers.aug.md#symbol-securityHeaders) with `name` = `"location"`; `value` = `location`; `name` = `"aug_authorize"`; `value` = `""`; `path` = `"/provider"`; `maxAge` = `0`; `secure` = `secureCookies` of `config`.
|
|
124
|
-
- Return call `HttpResponse` with `body` = the HTML element `p` containing `Returning to the application.` (rendered on the server with embedded text escaped); `status` = `303`; `headers` = `headers`.
|
|
125
|
-
- If they fail with `HttpError`, name the failure `error` and recover:
|
|
126
|
-
- Return call `HttpResponse` with `body` = call [`ProviderFailure`](views.aug.md#symbol-ProviderFailure) with `message` = `"The submitted form is invalid."`; `status` = `400`; `headers` = call [`securityHeaders`](../common/headers.aug.md#symbol-securityHeaders).
|
|
127
|
-
|
|
128
|
-
**Author documentation**
|
|
129
|
-
|
|
130
|
-
The browser binding and CSRF token are checked before credentials. Each form request is consumed once.
|
|
131
|
-
|
|
132
|
-
## Dependencies used by this file
|
|
133
|
-
|
|
134
|
-
Only referenced types and operations appear here. Each name links to its complete specification.
|
|
135
|
-
|
|
136
|
-
### [`Crypto`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto)
|
|
137
|
-
|
|
138
|
-
Capability interface from `august.crypto`.
|
|
139
|
-
|
|
140
|
-
- [`Crypto.decodeBase64url`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.decodeBase64url) (`input`: `string`) → `Bytes`; can fail with `CryptoError`.
|
|
141
|
-
- [`Crypto.equal`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.equal) (`left`: `Bytes`, `right`: `Bytes`) → `bool`.
|
|
142
|
-
- [`Crypto.passwordHash`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.passwordHash) (`password`: `Bytes`, `salt`: `Bytes`, `iterations`: `int`) → `Bytes`; can fail with `CryptoError`.
|
|
143
|
-
- [`Crypto.random`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.random) (`size`: `int`) → `Bytes`; can fail with `CryptoError`.
|
|
144
|
-
|
|
145
|
-
### [`ExpiringStore`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-ExpiringStore)
|
|
146
|
-
|
|
147
|
-
Capability interface from `august.memory`.
|
|
148
|
-
|
|
149
|
-
- [`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`.
|
|
150
|
-
- [`ExpiringStore.take`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-ExpiringStore.take) (`key`: `string`, `now`: `int`) → `optional T`.
|
|
151
|
-
|
|
152
|
-
### [`StoreFull`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-StoreFull)
|
|
153
|
-
|
|
154
|
-
Class from `august.memory`.
|
|
155
|
-
|
|
156
|
-
Used as a type or provider.
|
|
157
|
-
|
|
158
|
-
### [`Clock`](../.aug-spec/august/0.19.0/time/contracts.aug.md#symbol-Clock)
|
|
159
|
-
|
|
160
|
-
Capability interface from `august.time`.
|
|
161
|
-
|
|
162
|
-
- [`Clock.now`](../.aug-spec/august/0.19.0/time/contracts.aug.md#symbol-Clock.now) (no caller inputs) → `int`; can fail with `TimeError`.
|
|
163
|
-
|
|
164
|
-
### [`urlEncode`](../.aug-spec/august/0.19.0/web/contracts.aug.md#symbol-urlEncode)
|
|
165
|
-
|
|
166
|
-
Function from `august.web`.
|
|
167
|
-
|
|
168
|
-
- [`urlEncode`](../.aug-spec/august/0.19.0/web/contracts.aug.md#symbol-urlEncode) (`input`: `string`) → `string`; can fail with `HttpError`.
|
|
169
|
-
|
|
170
|
-
### [`securityHeaders`](../common/headers.aug.md#symbol-securityHeaders)
|
|
171
|
-
|
|
172
|
-
Function from `common`.
|
|
173
|
-
|
|
174
|
-
- [`securityHeaders`](../common/headers.aug.md#symbol-securityHeaders) (no caller inputs) → `Headers`; can fail with `HttpError`.
|
|
175
|
-
|
|
176
|
-
### [`withCookie`](../common/headers.aug.md#symbol-withCookie)
|
|
177
|
-
|
|
178
|
-
Function from `common`.
|
|
179
|
-
|
|
180
|
-
- [`withCookie`](../common/headers.aug.md#symbol-withCookie) (`headers`: `Headers`, `name`: `string`, `value`: `string`, `path`: `string`, `maxAge`: `int`, `secure`: `bool`) → `Headers`; can fail with `HttpError`.
|
|
181
|
-
|
|
182
|
-
### [`Settings`](../common/settings.aug.md#symbol-Settings)
|
|
183
|
-
|
|
184
|
-
Record.
|
|
185
|
-
|
|
186
|
-
- Read `baseUrl` (`string`).
|
|
187
|
-
- Read `callback` (`string`).
|
|
188
|
-
- Read `clientId` (`string`).
|
|
189
|
-
- Read `secureCookies` (`bool`).
|
|
190
|
-
|
|
191
|
-
### [`settings`](../common/settings.aug.md#symbol-settings)
|
|
192
|
-
|
|
193
|
-
Function from `common`.
|
|
194
|
-
|
|
195
|
-
- [`settings`](../common/settings.aug.md#symbol-settings) (no caller inputs) → [`Settings`](../common/settings.aug.md#symbol-Settings).
|
|
196
|
-
|
|
197
|
-
### [`AuthorizationCode`](contracts.aug.md#symbol-AuthorizationCode)
|
|
198
|
-
|
|
199
|
-
Record from `contracts`.
|
|
200
|
-
|
|
201
|
-
- Construct with `clientId`: `string`, `redirectUri`: `string`, `challenge`: `string`, `nonce`: `string`, `subject`: `string`, `name`: `string`, `expires`: `int` → [`AuthorizationCode`](contracts.aug.md#symbol-AuthorizationCode).
|
|
202
|
-
- Read `expires` (`int`).
|
|
203
|
-
|
|
204
|
-
### [`AuthorizationRequest`](contracts.aug.md#symbol-AuthorizationRequest)
|
|
205
|
-
|
|
206
|
-
Record from `contracts`.
|
|
207
|
-
|
|
208
|
-
- Construct with `clientId`: `string`, `redirectUri`: `string`, `state`: `string`, `nonce`: `string`, `challenge`: `string`, `browser`: `string`, `csrf`: `string`, `expires`: `int` → [`AuthorizationRequest`](contracts.aug.md#symbol-AuthorizationRequest).
|
|
209
|
-
- Read `browser` (`string`).
|
|
210
|
-
- Read `challenge` (`string`).
|
|
211
|
-
- Read `clientId` (`string`).
|
|
212
|
-
- Read `csrf` (`string`).
|
|
213
|
-
- Read `expires` (`int`).
|
|
214
|
-
- Read `nonce` (`string`).
|
|
215
|
-
- Read `redirectUri` (`string`).
|
|
216
|
-
- Read `state` (`string`).
|
|
217
|
-
|
|
218
|
-
### [`LoginError`](contracts.aug.md#symbol-LoginError)
|
|
219
|
-
|
|
220
|
-
Class from `contracts`.
|
|
221
|
-
|
|
222
|
-
- Construct with no caller inputs → [`LoginError`](contracts.aug.md#symbol-LoginError).
|
|
223
|
-
|
|
224
|
-
### [`LoginForm`](contracts.aug.md#symbol-LoginForm)
|
|
225
|
-
|
|
226
|
-
Record from `contracts`.
|
|
227
|
-
|
|
228
|
-
- Read `csrf` (`string`).
|
|
229
|
-
- Read `password` (`string`).
|
|
230
|
-
- Read `request_id` (`string`).
|
|
231
|
-
- Read `username` (`string`).
|
|
232
|
-
|
|
233
|
-
### [`verifyCredentials`](credentials.aug.md#symbol-verifyCredentials)
|
|
234
|
-
|
|
235
|
-
Function from `credentials`.
|
|
25
|
+
`providerLogin` handles `POST /provider/login`. The browser binding and CSRF token are checked before credentials. Each form request is consumed once.
|
|
236
26
|
|
|
237
|
-
|
|
27
|
+
It takes `form` as [`LoginForm`](contracts.aug.md#symbol-LoginForm) from the HTTP form, `browser` as `optional string` from the HTTP cookie `aug_authorize`, and `origin` as `optional string` from the HTTP header `origin`. It gets `crypto` ([`Crypto`](../.aug-spec/packages/%40git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/contracts.aug.md#symbol-Crypto)), `clock` ([`Clock`](../.aug-spec/packages/%40git/url_c092cd151499c4e1d8a1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.aug.md#symbol-Clock)), `requests` ([`ExpiringStore<AuthorizationRequest>`](../.aug-spec/packages/%40git/url_0eb7c89453c87681ed15/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/store.aug.md#symbol-ExpiringStore)), and `codes` ([`ExpiringStore<AuthorizationCode>`](../.aug-spec/packages/%40git/url_0eb7c89453c87681ed15/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/store.aug.md#symbol-ExpiringStore)) from dependency injection. Omitted optional inputs are null. The handler responds with HTTP 503 for `CryptoError`, HTTP 503 for `TimeError`, and HTTP 503 for [`StoreFull`](../.aug-spec/packages/%40git/url_0eb7c89453c87681ed15/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/store.aug.md#symbol-StoreFull).
|
|
238
28
|
|
|
239
|
-
|
|
29
|
+
It can also raise `HttpError`.
|
|
240
30
|
|
|
241
|
-
|
|
31
|
+
It gets `config` from [`settings`](../common/settings.aug.md#symbol-settings). If `origin` does not equal `config.baseUrl`, it returns HTTP 403 with [`ProviderFailure`](views.aug.md#symbol-ProviderFailure) showing `"The sign-in form must come from this app."` and [`securityHeaders`](../common/headers.aug.md#symbol-securityHeaders) headers. It obtains [`requests.take`](../.aug-spec/packages/%40git/url_0eb7c89453c87681ed15/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/store.aug.md#symbol-ExpiringStore.take) with `key` from `form.request_id` and `now` from [`clock.now`](../.aug-spec/packages/%40git/url_c092cd151499c4e1d8a1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.aug.md#symbol-Clock.now). If no value is found, it returns HTTP 400 with [`ProviderFailure`](views.aug.md#symbol-ProviderFailure) showing `"The sign-in request expired or was already used."` and [`securityHeaders`](../common/headers.aug.md#symbol-securityHeaders) headers.
|
|
242
32
|
|
|
243
|
-
- [`ProviderFailure`](views.aug.md#symbol-ProviderFailure) (`
|
|
33
|
+
The non-null result becomes `request`. If `browser` is null, it returns HTTP 403 with [`ProviderFailure`](views.aug.md#symbol-ProviderFailure) showing `"The browser binding is missing."` and [`securityHeaders`](../common/headers.aug.md#symbol-securityHeaders) headers. The non-null `browser` becomes `secret`. If [`crypto.equal`](../.aug-spec/packages/%40git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/contracts.aug.md#symbol-Crypto.equal) with `left` from the UTF-8 bytes of `secret` and `right` from the UTF-8 bytes of `request.browser` returns false or [`crypto.equal`](../.aug-spec/packages/%40git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/contracts.aug.md#symbol-Crypto.equal) with `left` from the UTF-8 bytes of `form.csrf` and `right` from the UTF-8 bytes of `request.csrf` returns false, it returns HTTP 403 with [`ProviderFailure`](views.aug.md#symbol-ProviderFailure) showing `"The sign-in form could not be verified."` and [`securityHeaders`](../common/headers.aug.md#symbol-securityHeaders) headers.
|
|
244
34
|
|
|
245
|
-
|
|
35
|
+
If [`verifyCredentials`](credentials.aug.md#symbol-verifyCredentials) with `form.username` and `form.password` using injected `crypto` returns false, it returns HTTP 401 with [`ProviderFailure`](views.aug.md#symbol-ProviderFailure) showing `"The username or password was not accepted."` and [`securityHeaders`](../common/headers.aug.md#symbol-securityHeaders) headers. It sets `now` to [`clock.now`](../.aug-spec/packages/%40git/url_c092cd151499c4e1d8a1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.aug.md#symbol-Clock.now). It sets `code` to the URL-safe base64 encoding of [`crypto.random`](../.aug-spec/packages/%40git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/contracts.aug.md#symbol-Crypto.random) with `size` `32`. It sets `grant` to an [`AuthorizationCode`](contracts.aug.md#symbol-AuthorizationCode) with `request.clientId`, `request.redirectUri`, `request.challenge`, `request.nonce`, `subject` `"demo-ada"`, `name` `"Ada"`, and `expires` from `now` plus `60`.
|
|
246
36
|
|
|
247
|
-
|
|
37
|
+
It calls [`codes.put`](../.aug-spec/packages/%40git/url_0eb7c89453c87681ed15/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/store.aug.md#symbol-ExpiringStore.put) with `key` from `code`, `value` from `grant`, `grant.expires`, and `now`. It builds `location` as the text `{request.redirectUri}?code={urlEncode with input from code}&state={urlEncode with input from request.state}`. It sets `headers` to [`withCookie`](../common/headers.aug.md#symbol-withCookie) with `headers` from [`securityHeaders`](../common/headers.aug.md#symbol-securityHeaders) with the header `"location"` set to `location`, `name` `"aug_authorize"`, `value` `""`, `path` `"/provider"`, `maxAge` `0`, and `secure` from `config.secureCookies`. It returns HTTP 303 with a paragraph containing `Returning to the application.` with escaped text and `headers` headers.
|
|
248
38
|
|
|
249
|
-
|
|
39
|
+
If this work raises `HttpError`, it returns HTTP 400 with [`ProviderFailure`](views.aug.md#symbol-ProviderFailure) showing `"The submitted form is invalid."` and [`securityHeaders`](../common/headers.aug.md#symbol-securityHeaders) headers.
|
|
250
40
|
|
|
251
|
-
##
|
|
41
|
+
## Dependencies
|
|
252
42
|
|
|
253
|
-
- `
|
|
254
|
-
- `Bytes.length` (no inputs) → `int`: Read the number of elements.
|
|
255
|
-
- `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`.
|
|
256
|
-
- `string.bytes` (no inputs) → `Bytes`: Encode this string as immutable UTF-8 bytes.
|
|
257
|
-
- `string.isToken` (`min`: `int`, `max`: `int`) → `bool`: Require an ASCII RFC 3986 unreserved token with a bounded length.
|
|
258
|
-
- `string.length` (no inputs) → `int`: Read the number of UTF-8 bytes. Unicode text is preserved losslessly.
|
|
43
|
+
It uses [`ExpiringStore`](../.aug-spec/packages/%40git/url_0eb7c89453c87681ed15/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/store.aug.md#symbol-ExpiringStore) ([`put`](../.aug-spec/packages/%40git/url_0eb7c89453c87681ed15/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/store.aug.md#symbol-ExpiringStore.put) and [`take`](../.aug-spec/packages/%40git/url_0eb7c89453c87681ed15/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/store.aug.md#symbol-ExpiringStore.take)) and [`StoreFull`](../.aug-spec/packages/%40git/url_0eb7c89453c87681ed15/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/store.aug.md#symbol-StoreFull) from `memory`. It uses [`urlEncode`](../.aug-spec/packages/%40git/url_897efafd565158fc4908/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.aug.md#symbol-urlEncode) from `web`. It uses [`Crypto`](../.aug-spec/packages/%40git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/contracts.aug.md#symbol-Crypto) ([`decodeBase64url`](../.aug-spec/packages/%40git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/contracts.aug.md#symbol-Crypto.decodeBase64url), [`equal`](../.aug-spec/packages/%40git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/contracts.aug.md#symbol-Crypto.equal), [`passwordHash`](../.aug-spec/packages/%40git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/contracts.aug.md#symbol-Crypto.passwordHash), and [`random`](../.aug-spec/packages/%40git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/contracts.aug.md#symbol-Crypto.random)) from `crypto`. It uses [`Clock`](../.aug-spec/packages/%40git/url_c092cd151499c4e1d8a1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.aug.md#symbol-Clock) ([`now`](../.aug-spec/packages/%40git/url_c092cd151499c4e1d8a1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.aug.md#symbol-Clock.now)) from `time`.
|
|
259
44
|
|
|
260
|
-
[
|
|
45
|
+
It uses [`securityHeaders`](../common/headers.aug.md#symbol-securityHeaders), [`withCookie`](../common/headers.aug.md#symbol-withCookie), and [`settings`](../common/settings.aug.md#symbol-settings) from `common`. It uses [`Settings`](../common/settings.aug.md#symbol-Settings) (`baseUrl`, `callback`, `clientId`, and `secureCookies`). It uses [`AuthorizationCode`](contracts.aug.md#symbol-AuthorizationCode) (`expires`), [`AuthorizationRequest`](contracts.aug.md#symbol-AuthorizationRequest) (`browser`, `challenge`, `clientId`, `csrf`, `expires`, `nonce`, `redirectUri`, and `state`), [`LoginError`](contracts.aug.md#symbol-LoginError), and [`LoginForm`](contracts.aug.md#symbol-LoginForm) (`csrf`, `password`, `request_id`, and `username`) from `contracts`. It uses [`verifyCredentials`](credentials.aug.md#symbol-verifyCredentials) from `credentials`.
|
|
261
46
|
|
|
262
|
-
|
|
47
|
+
It uses [`ProviderFailure`](views.aug.md#symbol-ProviderFailure) and [`ProviderLogin`](views.aug.md#symbol-ProviderLogin) from `views`.
|
|
263
48
|
|
|
264
|
-
|
|
49
|
+
Built-in operations follow the [language reference](https://greenpandastudios.github.io/augscript/language-constructs).
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// aug-spec: "contracts.aug.md" explains this file. Read it before changes; refresh with aug spec.
|
|
1
2
|
/** A provider request is bound to a browser cookie, a form CSRF token, and a registered client. */
|
|
2
3
|
record AuthorizationRequest(string clientId, string redirectUri, string state, string nonce, string challenge, string browser, string csrf, int expires)
|
|
3
4
|
/** Codes are short-lived, single-use and bound to a redirect URI and S256 challenge. */
|
|
@@ -1,193 +1,58 @@
|
|
|
1
1
|
<!-- Generated by aug spec. Edit the August source, then regenerate. -->
|
|
2
2
|
|
|
3
|
-
# `contracts.aug`
|
|
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
|
-
- [`AuthorizationRequest`](contracts.aug.md#symbol-AuthorizationRequest) is an immutable record.
|
|
10
|
-
- [`AuthorizationCode`](contracts.aug.md#symbol-AuthorizationCode) is an immutable record.
|
|
11
|
-
- [`IdClaims`](contracts.aug.md#symbol-IdClaims) is an immutable record.
|
|
12
|
-
- [`AccessGrant`](contracts.aug.md#symbol-AccessGrant) is an immutable record.
|
|
13
|
-
- [`TokenResponse`](contracts.aug.md#symbol-TokenResponse) is an immutable record.
|
|
14
|
-
- [`OAuthError`](contracts.aug.md#symbol-OAuthError) is an immutable record.
|
|
15
|
-
- [`TokenForm`](contracts.aug.md#symbol-TokenForm) is an immutable record.
|
|
16
|
-
- [`LoginForm`](contracts.aug.md#symbol-LoginForm) is an immutable record.
|
|
17
|
-
- [`UserInfo`](contracts.aug.md#symbol-UserInfo) is an immutable record.
|
|
18
|
-
- [`LoginError`](contracts.aug.md#symbol-LoginError) is a class implementing `Error`.
|
|
19
|
-
- [`CodeError`](contracts.aug.md#symbol-CodeError) is a class implementing `Error`.
|
|
3
|
+
# `contracts.aug`
|
|
20
4
|
|
|
21
5
|
<a id="symbol-AuthorizationRequest"></a>
|
|
6
|
+
## `AuthorizationRequest` · immutable record · [source](contracts.aug#L3)
|
|
22
7
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
[source](contracts.aug#L2)
|
|
26
|
-
|
|
27
|
-
Immutable record.
|
|
28
|
-
|
|
29
|
-
**Author documentation**
|
|
30
|
-
|
|
31
|
-
A provider request is bound to a browser cookie, a form CSRF token, and a registered client.
|
|
32
|
-
|
|
33
|
-
**Inputs**
|
|
34
|
-
|
|
35
|
-
- `clientId` (`string`) — required labeled input — stored as `clientId` and read-only after initialization.
|
|
36
|
-
- `redirectUri` (`string`) — required labeled input — stored as `redirectUri` and read-only after initialization.
|
|
37
|
-
- `state` (`string`) — required labeled input — stored as `state` and read-only after initialization.
|
|
38
|
-
- `nonce` (`string`) — required labeled input — stored as `nonce` and read-only after initialization.
|
|
39
|
-
- `challenge` (`string`) — required labeled input — stored as `challenge` and read-only after initialization.
|
|
40
|
-
- `browser` (`string`) — required labeled input — stored as `browser` and read-only after initialization.
|
|
41
|
-
- `csrf` (`string`) — required labeled input — stored as `csrf` and read-only after initialization.
|
|
42
|
-
- `expires` (`int`) — required labeled input — stored as `expires` and read-only after initialization.
|
|
8
|
+
A provider request is bound to a browser cookie, a form CSRF token, and a registered client. It takes `clientId`, `redirectUri`, `state`, `nonce`, `challenge`, `browser`, and `csrf` as strings, kept read-only and `expires` as an integer, kept read-only.
|
|
43
9
|
|
|
44
10
|
<a id="symbol-AuthorizationCode"></a>
|
|
11
|
+
## `AuthorizationCode` · immutable record · [source](contracts.aug#L5)
|
|
45
12
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
[source](contracts.aug#L4)
|
|
49
|
-
|
|
50
|
-
Immutable record.
|
|
51
|
-
|
|
52
|
-
**Author documentation**
|
|
53
|
-
|
|
54
|
-
Codes are short-lived, single-use and bound to a redirect URI and S256 challenge.
|
|
55
|
-
|
|
56
|
-
**Inputs**
|
|
57
|
-
|
|
58
|
-
- `clientId` (`string`) — required labeled input — stored as `clientId` and read-only after initialization.
|
|
59
|
-
- `redirectUri` (`string`) — required labeled input — stored as `redirectUri` and read-only after initialization.
|
|
60
|
-
- `challenge` (`string`) — required labeled input — stored as `challenge` and read-only after initialization.
|
|
61
|
-
- `nonce` (`string`) — required labeled input — stored as `nonce` and read-only after initialization.
|
|
62
|
-
- `subject` (`string`) — required labeled input — stored as `subject` and read-only after initialization.
|
|
63
|
-
- `name` (`string`) — required labeled input — stored as `name` and read-only after initialization.
|
|
64
|
-
- `expires` (`int`) — required labeled input — stored as `expires` and read-only after initialization.
|
|
13
|
+
Codes are short-lived, single-use and bound to a redirect URI and S256 challenge. It takes `clientId`, `redirectUri`, `challenge`, `nonce`, `subject`, and `name` as strings, kept read-only and `expires` as an integer, kept read-only.
|
|
65
14
|
|
|
66
15
|
<a id="symbol-IdClaims"></a>
|
|
16
|
+
## `IdClaims` · immutable record · [source](contracts.aug#L6)
|
|
67
17
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
[source](contracts.aug#L5)
|
|
71
|
-
|
|
72
|
-
Immutable record.
|
|
73
|
-
|
|
74
|
-
**Inputs**
|
|
75
|
-
|
|
76
|
-
- `iss` (`string`) — required labeled input — stored as `iss` and read-only after initialization.
|
|
77
|
-
- `sub` (`string`) — required labeled input — stored as `sub` and read-only after initialization.
|
|
78
|
-
- `aud` (`string`) — required labeled input — stored as `aud` and read-only after initialization.
|
|
79
|
-
- `exp` (`int`) — required labeled input — stored as `exp` and read-only after initialization.
|
|
80
|
-
- `iat` (`int`) — required labeled input — stored as `iat` and read-only after initialization.
|
|
81
|
-
- `nonce` (`string`) — required labeled input — stored as `nonce` and read-only after initialization.
|
|
82
|
-
- `name` (`string`) — required labeled input — stored as `name` and read-only after initialization.
|
|
18
|
+
It takes `iss`, `sub`, and `aud` as strings, kept read-only, `exp` and `iat` as integers, kept read-only, and `nonce` and `name` as strings, kept read-only.
|
|
83
19
|
|
|
84
20
|
<a id="symbol-AccessGrant"></a>
|
|
21
|
+
## `AccessGrant` · immutable record · [source](contracts.aug#L7)
|
|
85
22
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
[source](contracts.aug#L6)
|
|
89
|
-
|
|
90
|
-
Immutable record.
|
|
91
|
-
|
|
92
|
-
**Inputs**
|
|
93
|
-
|
|
94
|
-
- `subject` (`string`) — required labeled input — stored as `subject` and read-only after initialization.
|
|
95
|
-
- `name` (`string`) — required labeled input — stored as `name` and read-only after initialization.
|
|
96
|
-
- `expires` (`int`) — required labeled input — stored as `expires` and read-only after initialization.
|
|
23
|
+
It takes `subject` and `name` as strings, kept read-only and `expires` as an integer, kept read-only.
|
|
97
24
|
|
|
98
25
|
<a id="symbol-TokenResponse"></a>
|
|
26
|
+
## `TokenResponse` · immutable record · [source](contracts.aug#L8)
|
|
99
27
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
[source](contracts.aug#L7)
|
|
103
|
-
|
|
104
|
-
Immutable record.
|
|
105
|
-
|
|
106
|
-
**Inputs**
|
|
107
|
-
|
|
108
|
-
- `token_type` (`string`) — required labeled input — stored as `token_type` and read-only after initialization.
|
|
109
|
-
- `access_token` (`string`) — required labeled input — stored as `access_token` and read-only after initialization.
|
|
110
|
-
- `id_token` (`string`) — required labeled input — stored as `id_token` and read-only after initialization.
|
|
111
|
-
- `expires_in` (`int`) — required labeled input — stored as `expires_in` and read-only after initialization.
|
|
112
|
-
- `scope` (`string`) — required labeled input — stored as `scope` and read-only after initialization.
|
|
28
|
+
It takes `token_type`, `access_token`, and `id_token` as strings, kept read-only, `expires_in` as an integer, kept read-only, and `scope` as a string, kept read-only.
|
|
113
29
|
|
|
114
30
|
<a id="symbol-OAuthError"></a>
|
|
31
|
+
## `OAuthError` · immutable record · [source](contracts.aug#L9)
|
|
115
32
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
[source](contracts.aug#L8)
|
|
119
|
-
|
|
120
|
-
Immutable record.
|
|
121
|
-
|
|
122
|
-
**Inputs**
|
|
123
|
-
|
|
124
|
-
- `error` (`string`) — required labeled input — stored as `error` and read-only after initialization.
|
|
125
|
-
- `error_description` (`string`) — required labeled input — stored as `error_description` and read-only after initialization.
|
|
33
|
+
It takes `error` and `error_description` as strings, kept read-only.
|
|
126
34
|
|
|
127
35
|
<a id="symbol-TokenForm"></a>
|
|
36
|
+
## `TokenForm` · immutable record · [source](contracts.aug#L10)
|
|
128
37
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
[source](contracts.aug#L9)
|
|
132
|
-
|
|
133
|
-
Immutable record.
|
|
134
|
-
|
|
135
|
-
**Inputs**
|
|
136
|
-
|
|
137
|
-
- `grant_type` (`string`) — required labeled input — stored as `grant_type` and read-only after initialization.
|
|
138
|
-
- `code` (`string`) — required labeled input — stored as `code` and read-only after initialization.
|
|
139
|
-
- `redirect_uri` (`string`) — required labeled input — stored as `redirect_uri` and read-only after initialization.
|
|
140
|
-
- `client_id` (`string`) — required labeled input — stored as `client_id` and read-only after initialization.
|
|
141
|
-
- `code_verifier` (`string`) — required labeled input — stored as `code_verifier` and read-only after initialization.
|
|
38
|
+
It takes `grant_type`, `code`, `redirect_uri`, `client_id`, and `code_verifier` as strings, kept read-only.
|
|
142
39
|
|
|
143
40
|
<a id="symbol-LoginForm"></a>
|
|
41
|
+
## `LoginForm` · immutable record · [source](contracts.aug#L11)
|
|
144
42
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
[source](contracts.aug#L10)
|
|
148
|
-
|
|
149
|
-
Immutable record.
|
|
150
|
-
|
|
151
|
-
**Inputs**
|
|
152
|
-
|
|
153
|
-
- `request_id` (`string`) — required labeled input — stored as `request_id` and read-only after initialization.
|
|
154
|
-
- `csrf` (`string`) — required labeled input — stored as `csrf` and read-only after initialization.
|
|
155
|
-
- `username` (`string`) — required labeled input — stored as `username` and read-only after initialization.
|
|
156
|
-
- `password` (`string`) — required labeled input — stored as `password` and read-only after initialization.
|
|
43
|
+
It takes `request_id`, `csrf`, `username`, and `password` as strings, kept read-only.
|
|
157
44
|
|
|
158
45
|
<a id="symbol-UserInfo"></a>
|
|
46
|
+
## `UserInfo` · immutable record · [source](contracts.aug#L12)
|
|
159
47
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
[source](contracts.aug#L11)
|
|
163
|
-
|
|
164
|
-
Immutable record.
|
|
165
|
-
|
|
166
|
-
**Inputs**
|
|
167
|
-
|
|
168
|
-
- `sub` (`string`) — required labeled input — stored as `sub` and read-only after initialization.
|
|
169
|
-
- `name` (`string`) — required labeled input — stored as `name` and read-only after initialization.
|
|
48
|
+
It takes `sub` and `name` as strings, kept read-only.
|
|
170
49
|
|
|
171
50
|
<a id="symbol-LoginError"></a>
|
|
51
|
+
## `LoginError` · class · [source](contracts.aug#L13)
|
|
172
52
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
[source](contracts.aug#L12)
|
|
176
|
-
|
|
177
|
-
Behavioral class.
|
|
178
|
-
|
|
179
|
-
Satisfies `Error`.
|
|
53
|
+
It implements `Error`.
|
|
180
54
|
|
|
181
55
|
<a id="symbol-CodeError"></a>
|
|
56
|
+
## `CodeError` · class · [source](contracts.aug#L15)
|
|
182
57
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
[source](contracts.aug#L14)
|
|
186
|
-
|
|
187
|
-
Behavioral class.
|
|
188
|
-
|
|
189
|
-
Satisfies `Error`.
|
|
190
|
-
|
|
191
|
-
## Shared language rules
|
|
192
|
-
|
|
193
|
-
See the [language reference](https://greenpandastudios.github.io/augscript/reference) for numeric, equality, ownership, and task rules.
|
|
58
|
+
It implements `Error`.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
// aug-spec: "credentials.aug.md" explains this file. Read it before changes; refresh with aug spec.
|
|
2
|
+
import Crypto from crypto
|
|
2
3
|
/** One development account with a PBKDF2-HMAC-SHA256 verifier. Production account storage is deliberately a separate capability. */
|
|
3
|
-
verifyCredentials(string username, string password, resolve Crypto crypto)
|
|
4
|
+
verifyCredentials(string username, string password, resolve Crypto crypto) :
|
|
4
5
|
if username.length() > 64 or password.length() > 256:
|
|
5
6
|
return false
|
|
6
7
|
actual = crypto.passwordHash(password=password.bytes(), salt="August demo salt v1".bytes(), iterations=600000)
|