@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
|
@@ -49,16 +49,17 @@ pageClass: aug-example-page
|
|
|
49
49
|
::: code-group
|
|
50
50
|
|
|
51
51
|
```aug [Indentation]
|
|
52
|
+
// aug-spec: "login.aug.md" explains this file. Read it before changes; refresh with aug spec.
|
|
52
53
|
import LoginTransaction and SessionClaims and SessionError from contracts
|
|
53
54
|
import discover and responseJson and validateIdentity from protocol
|
|
54
55
|
import TokenResponse and UserInfo from provider
|
|
55
56
|
import settings and SigningKeys and KeyError and securityHeaders and withCookie from common
|
|
56
|
-
import Crypto and RsaJwks and signJwt and JwtError from
|
|
57
|
-
import Clock from
|
|
58
|
-
import HttpClient and urlEncode from
|
|
59
|
-
import ExpiringStore and StoreFull from
|
|
57
|
+
import Crypto and RsaJwks and signJwt and JwtError from crypto
|
|
58
|
+
import Clock from time
|
|
59
|
+
import HttpClient and urlEncode from web
|
|
60
|
+
import ExpiringStore and StoreFull from memory
|
|
60
61
|
/** Start a browser-bound, short-lived transaction. The PKCE verifier stays on the server. */
|
|
61
|
-
endpoint GET "/login/start" as startLogin(resolve Crypto crypto, resolve Clock clock, resolve HttpClient client, resolve ExpiringStore<LoginTransaction> transactions)
|
|
62
|
+
endpoint GET "/login/start" as startLogin(resolve Crypto crypto, resolve Clock clock, resolve HttpClient client, resolve ExpiringStore<LoginTransaction> transactions) unless SessionError with status 502 and CryptoError with status 503 and TimeError with status 503 and StoreFull with status 503 and HttpError:
|
|
62
63
|
config = settings()
|
|
63
64
|
document = discover()
|
|
64
65
|
browser = crypto.random(size=32).base64url()
|
|
@@ -66,13 +67,29 @@ endpoint GET "/login/start" as startLogin(resolve Crypto crypto, resolve Clock c
|
|
|
66
67
|
nonce = crypto.random(size=32).base64url()
|
|
67
68
|
verifier = crypto.random(size=32).base64url()
|
|
68
69
|
transaction = LoginTransaction(state, nonce, verifier, expires=clock.now() + 300)
|
|
69
|
-
transactions.put(
|
|
70
|
+
transactions.put(
|
|
71
|
+
key=browser,
|
|
72
|
+
value=transaction,
|
|
73
|
+
expires=transaction.expires,
|
|
74
|
+
now=clock.now()
|
|
75
|
+
)
|
|
70
76
|
challenge = crypto.sha256(input=verifier.bytes()).base64url()
|
|
71
77
|
location = document.authorization_endpoint + "?response_type=code&client_id=" + urlEncode(input=config.clientId) + "&redirect_uri=" + urlEncode(input=config.callback) + "&scope=openid%20profile&state=" + urlEncode(input=state) + "&nonce=" + urlEncode(input=nonce) + "&code_challenge=" + urlEncode(input=challenge) + "&code_challenge_method=S256"
|
|
72
|
-
headers = withCookie(
|
|
73
|
-
|
|
78
|
+
headers = withCookie(
|
|
79
|
+
headers=securityHeaders().with(name="location", value=location),
|
|
80
|
+
name="aug_login",
|
|
81
|
+
value=browser,
|
|
82
|
+
path="/login",
|
|
83
|
+
maxAge=300,
|
|
84
|
+
secure=config.secureCookies
|
|
85
|
+
)
|
|
86
|
+
return HttpResponse(
|
|
87
|
+
body=<p>Opening the identity provider.</p>,
|
|
88
|
+
status=303,
|
|
89
|
+
headers=headers
|
|
90
|
+
)
|
|
74
91
|
/** Exchange a one-use code over HTTP, verify the provider JWT/JWKS and UserInfo subject, then issue a distinct app-session JWT. */
|
|
75
|
-
endpoint GET "/login/callback" as loginCallback(string code from query, string state from query, optional string browser from cookie "aug_login", resolve Crypto crypto, resolve Clock clock, resolve HttpClient client, resolve SigningKeys keys, resolve ExpiringStore<LoginTransaction> transactions, resolve ExpiringStore<SessionClaims> sessions)
|
|
92
|
+
endpoint GET "/login/callback" as loginCallback(string code from query, string state from query, optional string browser from cookie "aug_login", resolve Crypto crypto, resolve Clock clock, resolve HttpClient client, resolve SigningKeys keys, resolve ExpiringStore<LoginTransaction> transactions, resolve ExpiringStore<SessionClaims> sessions) unless SessionError with status 400 and CryptoError with status 503 and TimeError with status 503 and KeyError and StoreFull with status 503 and JwtError and JsonError and HttpError:
|
|
76
93
|
if not code.isToken(min=43, max=43) or not state.isToken(min=43, max=43):
|
|
77
94
|
throw SessionError()
|
|
78
95
|
match browser:
|
|
@@ -83,41 +100,108 @@ endpoint GET "/login/callback" as loginCallback(string code from query, string s
|
|
|
83
100
|
when null:
|
|
84
101
|
throw SessionError()
|
|
85
102
|
when some transaction:
|
|
86
|
-
if not crypto.equal(
|
|
103
|
+
if not crypto.equal(
|
|
104
|
+
left=transaction.state.bytes(),
|
|
105
|
+
right=state.bytes()
|
|
106
|
+
):
|
|
87
107
|
throw SessionError()
|
|
88
108
|
config = settings()
|
|
89
109
|
document = discover()
|
|
90
110
|
body = "grant_type=authorization_code&code=" + urlEncode(input=code) + "&redirect_uri=" + urlEncode(input=config.callback) + "&client_id=" + urlEncode(input=config.clientId) + "&code_verifier=" + urlEncode(input=transaction.verifier)
|
|
91
|
-
headers = Headers().with(
|
|
92
|
-
|
|
111
|
+
headers = Headers().with(
|
|
112
|
+
name="content-type",
|
|
113
|
+
value="application/x-www-form-urlencoded"
|
|
114
|
+
)
|
|
115
|
+
tokens = responseJson(
|
|
116
|
+
response=client.request(
|
|
117
|
+
method="POST",
|
|
118
|
+
url=document.token_endpoint,
|
|
119
|
+
headers,
|
|
120
|
+
body=body.bytes()
|
|
121
|
+
)
|
|
122
|
+
).decode<TokenResponse>()
|
|
93
123
|
if tokens.token_type != "Bearer" or not tokens.access_token.isToken(min=43, max=43) or tokens.expires_in <= 0:
|
|
94
124
|
throw SessionError()
|
|
95
|
-
jwks = responseJson(
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
125
|
+
jwks = responseJson(
|
|
126
|
+
response=client.request(method="GET", url=document.jwks_uri)
|
|
127
|
+
).decode<RsaJwks>()
|
|
128
|
+
identity = validateIdentity(
|
|
129
|
+
token=tokens.id_token,
|
|
130
|
+
nonce=transaction.nonce,
|
|
131
|
+
now=clock.now(),
|
|
132
|
+
jwks
|
|
133
|
+
)
|
|
134
|
+
authHeaders = Headers().with(
|
|
135
|
+
name="authorization",
|
|
136
|
+
value="Bearer " + tokens.access_token
|
|
137
|
+
)
|
|
138
|
+
user = responseJson(
|
|
139
|
+
response=client.request(
|
|
140
|
+
method="GET",
|
|
141
|
+
url=document.userinfo_endpoint,
|
|
142
|
+
headers=authHeaders
|
|
143
|
+
)
|
|
144
|
+
).decode<UserInfo>()
|
|
99
145
|
if user.sub != identity.sub:
|
|
100
146
|
throw SessionError()
|
|
101
147
|
now = clock.now()
|
|
102
|
-
session = SessionClaims(
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
148
|
+
session = SessionClaims(
|
|
149
|
+
iss=config.baseUrl + "/app",
|
|
150
|
+
sub=identity.sub,
|
|
151
|
+
aud="august-app",
|
|
152
|
+
exp=now + config.sessionSeconds,
|
|
153
|
+
iat=now,
|
|
154
|
+
jti=crypto.random(size=32).base64url(),
|
|
155
|
+
csrf=crypto.random(size=32).base64url(),
|
|
156
|
+
name=user.name
|
|
157
|
+
)
|
|
158
|
+
jwt = signJwt(
|
|
159
|
+
key=keys.session(),
|
|
160
|
+
claims=Json(value=session),
|
|
161
|
+
kid="session-1",
|
|
162
|
+
tokenType="august-session+jwt"
|
|
163
|
+
)
|
|
164
|
+
sessions.put(
|
|
165
|
+
key=session.jti,
|
|
166
|
+
value=session,
|
|
167
|
+
expires=session.exp,
|
|
168
|
+
now=now
|
|
169
|
+
)
|
|
170
|
+
responseHeaders = withCookie(
|
|
171
|
+
headers=securityHeaders().with(name="location", value="/"),
|
|
172
|
+
name="aug_session",
|
|
173
|
+
value=jwt,
|
|
174
|
+
path="/",
|
|
175
|
+
maxAge=config.sessionSeconds,
|
|
176
|
+
secure=config.secureCookies
|
|
177
|
+
)
|
|
178
|
+
responseHeaders = withCookie(
|
|
179
|
+
headers=responseHeaders,
|
|
180
|
+
name="aug_login",
|
|
181
|
+
value="",
|
|
182
|
+
path="/login",
|
|
183
|
+
maxAge=0,
|
|
184
|
+
secure=config.secureCookies
|
|
185
|
+
)
|
|
186
|
+
return HttpResponse(
|
|
187
|
+
body=<p>Signed in.</p>,
|
|
188
|
+
status=303,
|
|
189
|
+
headers=responseHeaders
|
|
190
|
+
)
|
|
108
191
|
```
|
|
109
192
|
|
|
110
193
|
```aug [Braces]
|
|
194
|
+
// aug-spec: "login.aug.md" explains this file. Read it before changes; refresh with aug spec.
|
|
111
195
|
import LoginTransaction and SessionClaims and SessionError from contracts
|
|
112
196
|
import discover and responseJson and validateIdentity from protocol
|
|
113
197
|
import TokenResponse and UserInfo from provider
|
|
114
198
|
import settings and SigningKeys and KeyError and securityHeaders and withCookie from common
|
|
115
|
-
import Crypto and RsaJwks and signJwt and JwtError from
|
|
116
|
-
import Clock from
|
|
117
|
-
import HttpClient and urlEncode from
|
|
118
|
-
import ExpiringStore and StoreFull from
|
|
199
|
+
import Crypto and RsaJwks and signJwt and JwtError from crypto
|
|
200
|
+
import Clock from time
|
|
201
|
+
import HttpClient and urlEncode from web
|
|
202
|
+
import ExpiringStore and StoreFull from memory
|
|
119
203
|
/** Start a browser-bound, short-lived transaction. The PKCE verifier stays on the server. */
|
|
120
|
-
endpoint GET "/login/start" as startLogin(resolve Crypto crypto, resolve Clock clock, resolve HttpClient client, resolve ExpiringStore<LoginTransaction> transactions)
|
|
204
|
+
endpoint GET "/login/start" as startLogin(resolve Crypto crypto, resolve Clock clock, resolve HttpClient client, resolve ExpiringStore<LoginTransaction> transactions) unless SessionError with status 502 and CryptoError with status 503 and TimeError with status 503 and StoreFull with status 503 and HttpError {
|
|
121
205
|
config = settings()
|
|
122
206
|
document = discover()
|
|
123
207
|
browser = crypto.random(size=32).base64url()
|
|
@@ -125,14 +209,30 @@ endpoint GET "/login/start" as startLogin(resolve Crypto crypto, resolve Clock c
|
|
|
125
209
|
nonce = crypto.random(size=32).base64url()
|
|
126
210
|
verifier = crypto.random(size=32).base64url()
|
|
127
211
|
transaction = LoginTransaction(state, nonce, verifier, expires=clock.now() + 300)
|
|
128
|
-
transactions.put(
|
|
212
|
+
transactions.put(
|
|
213
|
+
key=browser,
|
|
214
|
+
value=transaction,
|
|
215
|
+
expires=transaction.expires,
|
|
216
|
+
now=clock.now()
|
|
217
|
+
)
|
|
129
218
|
challenge = crypto.sha256(input=verifier.bytes()).base64url()
|
|
130
219
|
location = document.authorization_endpoint + "?response_type=code&client_id=" + urlEncode(input=config.clientId) + "&redirect_uri=" + urlEncode(input=config.callback) + "&scope=openid%20profile&state=" + urlEncode(input=state) + "&nonce=" + urlEncode(input=nonce) + "&code_challenge=" + urlEncode(input=challenge) + "&code_challenge_method=S256"
|
|
131
|
-
headers = withCookie(
|
|
132
|
-
|
|
220
|
+
headers = withCookie(
|
|
221
|
+
headers=securityHeaders().with(name="location", value=location),
|
|
222
|
+
name="aug_login",
|
|
223
|
+
value=browser,
|
|
224
|
+
path="/login",
|
|
225
|
+
maxAge=300,
|
|
226
|
+
secure=config.secureCookies
|
|
227
|
+
)
|
|
228
|
+
return HttpResponse(
|
|
229
|
+
body=<p>Opening the identity provider.</p>,
|
|
230
|
+
status=303,
|
|
231
|
+
headers=headers
|
|
232
|
+
)
|
|
133
233
|
}
|
|
134
234
|
/** Exchange a one-use code over HTTP, verify the provider JWT/JWKS and UserInfo subject, then issue a distinct app-session JWT. */
|
|
135
|
-
endpoint GET "/login/callback" as loginCallback(string code from query, string state from query, optional string browser from cookie "aug_login", resolve Crypto crypto, resolve Clock clock, resolve HttpClient client, resolve SigningKeys keys, resolve ExpiringStore<LoginTransaction> transactions, resolve ExpiringStore<SessionClaims> sessions)
|
|
235
|
+
endpoint GET "/login/callback" as loginCallback(string code from query, string state from query, optional string browser from cookie "aug_login", resolve Crypto crypto, resolve Clock clock, resolve HttpClient client, resolve SigningKeys keys, resolve ExpiringStore<LoginTransaction> transactions, resolve ExpiringStore<SessionClaims> sessions) unless SessionError with status 400 and CryptoError with status 503 and TimeError with status 503 and KeyError and StoreFull with status 503 and JwtError and JsonError and HttpError {
|
|
136
236
|
if not code.isToken(min=43, max=43) or not state.isToken(min=43, max=43) {
|
|
137
237
|
throw SessionError()
|
|
138
238
|
}
|
|
@@ -146,31 +246,97 @@ endpoint GET "/login/callback" as loginCallback(string code from query, string s
|
|
|
146
246
|
throw SessionError()
|
|
147
247
|
}
|
|
148
248
|
when some transaction {
|
|
149
|
-
if not crypto.equal(
|
|
249
|
+
if not crypto.equal(
|
|
250
|
+
left=transaction.state.bytes(),
|
|
251
|
+
right=state.bytes()
|
|
252
|
+
) {
|
|
150
253
|
throw SessionError()
|
|
151
254
|
}
|
|
152
255
|
config = settings()
|
|
153
256
|
document = discover()
|
|
154
257
|
body = "grant_type=authorization_code&code=" + urlEncode(input=code) + "&redirect_uri=" + urlEncode(input=config.callback) + "&client_id=" + urlEncode(input=config.clientId) + "&code_verifier=" + urlEncode(input=transaction.verifier)
|
|
155
|
-
headers = Headers().with(
|
|
156
|
-
|
|
258
|
+
headers = Headers().with(
|
|
259
|
+
name="content-type",
|
|
260
|
+
value="application/x-www-form-urlencoded"
|
|
261
|
+
)
|
|
262
|
+
tokens = responseJson(
|
|
263
|
+
response=client.request(
|
|
264
|
+
method="POST",
|
|
265
|
+
url=document.token_endpoint,
|
|
266
|
+
headers,
|
|
267
|
+
body=body.bytes()
|
|
268
|
+
)
|
|
269
|
+
).decode<TokenResponse>()
|
|
157
270
|
if tokens.token_type != "Bearer" or not tokens.access_token.isToken(min=43, max=43) or tokens.expires_in <= 0 {
|
|
158
271
|
throw SessionError()
|
|
159
272
|
}
|
|
160
|
-
jwks = responseJson(
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
273
|
+
jwks = responseJson(
|
|
274
|
+
response=client.request(method="GET", url=document.jwks_uri)
|
|
275
|
+
).decode<RsaJwks>()
|
|
276
|
+
identity = validateIdentity(
|
|
277
|
+
token=tokens.id_token,
|
|
278
|
+
nonce=transaction.nonce,
|
|
279
|
+
now=clock.now(),
|
|
280
|
+
jwks
|
|
281
|
+
)
|
|
282
|
+
authHeaders = Headers().with(
|
|
283
|
+
name="authorization",
|
|
284
|
+
value="Bearer " + tokens.access_token
|
|
285
|
+
)
|
|
286
|
+
user = responseJson(
|
|
287
|
+
response=client.request(
|
|
288
|
+
method="GET",
|
|
289
|
+
url=document.userinfo_endpoint,
|
|
290
|
+
headers=authHeaders
|
|
291
|
+
)
|
|
292
|
+
).decode<UserInfo>()
|
|
164
293
|
if user.sub != identity.sub {
|
|
165
294
|
throw SessionError()
|
|
166
295
|
}
|
|
167
296
|
now = clock.now()
|
|
168
|
-
session = SessionClaims(
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
297
|
+
session = SessionClaims(
|
|
298
|
+
iss=config.baseUrl + "/app",
|
|
299
|
+
sub=identity.sub,
|
|
300
|
+
aud="august-app",
|
|
301
|
+
exp=now + config.sessionSeconds,
|
|
302
|
+
iat=now,
|
|
303
|
+
jti=crypto.random(size=32).base64url(),
|
|
304
|
+
csrf=crypto.random(size=32).base64url(),
|
|
305
|
+
name=user.name
|
|
306
|
+
)
|
|
307
|
+
jwt = signJwt(
|
|
308
|
+
key=keys.session(),
|
|
309
|
+
claims=Json(value=session),
|
|
310
|
+
kid="session-1",
|
|
311
|
+
tokenType="august-session+jwt"
|
|
312
|
+
)
|
|
313
|
+
sessions.put(
|
|
314
|
+
key=session.jti,
|
|
315
|
+
value=session,
|
|
316
|
+
expires=session.exp,
|
|
317
|
+
now=now
|
|
318
|
+
)
|
|
319
|
+
responseHeaders = withCookie(
|
|
320
|
+
headers=securityHeaders().with(name="location", value="/"),
|
|
321
|
+
name="aug_session",
|
|
322
|
+
value=jwt,
|
|
323
|
+
path="/",
|
|
324
|
+
maxAge=config.sessionSeconds,
|
|
325
|
+
secure=config.secureCookies
|
|
326
|
+
)
|
|
327
|
+
responseHeaders = withCookie(
|
|
328
|
+
headers=responseHeaders,
|
|
329
|
+
name="aug_login",
|
|
330
|
+
value="",
|
|
331
|
+
path="/login",
|
|
332
|
+
maxAge=0,
|
|
333
|
+
secure=config.secureCookies
|
|
334
|
+
)
|
|
335
|
+
return HttpResponse(
|
|
336
|
+
body=<p>Signed in.</p>,
|
|
337
|
+
status=303,
|
|
338
|
+
headers=responseHeaders
|
|
339
|
+
)
|
|
174
340
|
}
|
|
175
341
|
}
|
|
176
342
|
}
|
|
@@ -186,329 +352,53 @@ endpoint GET "/login/callback" as loginCallback(string code from query, string s
|
|
|
186
352
|
|
|
187
353
|
## Compiled specification {#specification}
|
|
188
354
|
|
|
189
|
-
|
|
355
|
+
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.
|
|
190
356
|
|
|
191
|
-
###
|
|
357
|
+
### `startLogin` · [source](login.md#code) {#symbol-startLogin}
|
|
192
358
|
|
|
193
|
-
- [`
|
|
194
|
-
- [`loginCallback`](login.md#symbol-loginCallback) handles `GET` `/login/callback` returning `HttpResponse<Html>`.
|
|
359
|
+
`startLogin` handles `GET /login/start`. Start a browser-bound, short-lived transaction. The PKCE verifier stays on the server. It gets `crypto` ([`Crypto`](../dependencies/packages/%40git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/contracts.md#symbol-Crypto)), `clock` ([`Clock`](../dependencies/packages/%40git/url_c092cd151499c4e1d8a1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.md#symbol-Clock)), `client` ([`HttpClient`](../dependencies/packages/%40git/url_897efafd565158fc4908/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.md#symbol-HttpClient)), and `transactions` ([`ExpiringStore<LoginTransaction>`](../dependencies/packages/%40git/url_0eb7c89453c87681ed15/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/store.md#symbol-ExpiringStore)) from dependency injection.
|
|
195
360
|
|
|
196
|
-
|
|
361
|
+
The handler responds with HTTP 502 for [`SessionError`](contracts.md#symbol-SessionError), HTTP 503 for `CryptoError`, HTTP 503 for `TimeError`, and HTTP 503 for [`StoreFull`](../dependencies/packages/%40git/url_0eb7c89453c87681ed15/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/store.md#symbol-StoreFull). It can also raise `HttpError`.
|
|
197
362
|
|
|
198
|
-
[
|
|
199
|
-
|
|
200
|
-
**Inputs**
|
|
201
|
-
|
|
202
|
-
- `crypto` ([`Crypto`](../dependencies/august/0.19.0/crypto/contracts.md#symbol-Crypto)) — injected; callers omit it.
|
|
203
|
-
- `clock` ([`Clock`](../dependencies/august/0.19.0/time/contracts.md#symbol-Clock)) — injected; callers omit it.
|
|
204
|
-
- `client` ([`HttpClient`](../dependencies/august/0.19.0/web/contracts.md#symbol-HttpClient)) — injected; callers omit it.
|
|
205
|
-
- `transactions` ([`ExpiringStore<LoginTransaction>`](../dependencies/august/0.19.0/memory/store.md#symbol-ExpiringStore)) — injected; callers omit it.
|
|
206
|
-
|
|
207
|
-
Returns: `HttpResponse<Html>`.
|
|
208
|
-
|
|
209
|
-
Capabilities: [`crypto.random`](../dependencies/august/0.19.0/crypto/contracts.md#symbol-Crypto.random), [`crypto.sha256`](../dependencies/august/0.19.0/crypto/contracts.md#symbol-Crypto.sha256), [`clock.now`](../dependencies/august/0.19.0/time/contracts.md#symbol-Clock.now), [`client.request`](../dependencies/august/0.19.0/web/contracts.md#symbol-HttpClient.request), [`transactions.put`](../dependencies/august/0.19.0/memory/store.md#symbol-ExpiringStore.put).
|
|
210
|
-
|
|
211
|
-
Can fail with `SessionError`, `CryptoError`, `TimeError`, `StoreFull`, `HttpError`. Callers must catch or propagate these errors.
|
|
212
|
-
|
|
213
|
-
HTTP route: `GET` `/login/start`. Use status 200 when the handler returns a body; a returned HttpResponse can set its own status. An unhandled request failure returns status 500 and cancels its request tasks.
|
|
214
|
-
|
|
215
|
-
Declared HTTP failures: [`SessionError`](contracts.md#symbol-SessionError) returns status 502; `CryptoError` returns status 503; `TimeError` returns status 503; [`StoreFull`](../dependencies/august/0.19.0/memory/store.md#symbol-StoreFull) returns status 503.
|
|
216
|
-
|
|
217
|
-
**What it does**
|
|
218
|
-
|
|
219
|
-
- Set `config` to call [`settings`](../common/settings.md#symbol-settings).
|
|
220
|
-
- Set `document` to call [`discover`](protocol.md#symbol-discover); inject `client` from `client`.
|
|
221
|
-
- Set `browser` to call `base64url` on call [`Crypto.random`](../dependencies/august/0.19.0/crypto/contracts.md#symbol-Crypto.random) on `crypto` with `size` = `32`.
|
|
222
|
-
- Set `state` to call `base64url` on call [`Crypto.random`](../dependencies/august/0.19.0/crypto/contracts.md#symbol-Crypto.random) on `crypto` with `size` = `32`.
|
|
223
|
-
- Set `nonce` to call `base64url` on call [`Crypto.random`](../dependencies/august/0.19.0/crypto/contracts.md#symbol-Crypto.random) on `crypto` with `size` = `32`.
|
|
224
|
-
- Set `verifier` to call `base64url` on call [`Crypto.random`](../dependencies/august/0.19.0/crypto/contracts.md#symbol-Crypto.random) on `crypto` with `size` = `32`.
|
|
225
|
-
- Set `transaction` to call [`LoginTransaction`](contracts.md#symbol-LoginTransaction) with `state` = `state`; `nonce` = `nonce`; `verifier` = `verifier`; `expires` = (call [`Clock.now`](../dependencies/august/0.19.0/time/contracts.md#symbol-Clock.now) on `clock` plus `300`).
|
|
226
|
-
- Call [`ExpiringStore.put`](../dependencies/august/0.19.0/memory/store.md#symbol-ExpiringStore.put) on `transactions` with `key` = `browser`; `value` = `transaction`; `expires` = `expires` of `transaction`; `now` = call [`Clock.now`](../dependencies/august/0.19.0/time/contracts.md#symbol-Clock.now) on `clock`.
|
|
227
|
-
- Set `challenge` to call `base64url` on call [`Crypto.sha256`](../dependencies/august/0.19.0/crypto/contracts.md#symbol-Crypto.sha256) on `crypto` with `input` = call `bytes` on `verifier`.
|
|
228
|
-
- Build `location` by joining these text parts without separators, in order:
|
|
229
|
-
1. `authorization_endpoint` of `document`
|
|
230
|
-
2. `"?response_type=code&client_id="`
|
|
231
|
-
3. call [`urlEncode`](../dependencies/august/0.19.0/web/contracts.md#symbol-urlEncode) with `input` = `clientId` of `config`
|
|
232
|
-
4. `"&redirect_uri="`
|
|
233
|
-
5. call [`urlEncode`](../dependencies/august/0.19.0/web/contracts.md#symbol-urlEncode) with `input` = `callback` of `config`
|
|
234
|
-
6. `"&scope=openid%20profile&state="`
|
|
235
|
-
7. call [`urlEncode`](../dependencies/august/0.19.0/web/contracts.md#symbol-urlEncode) with `input` = `state`
|
|
236
|
-
8. `"&nonce="`
|
|
237
|
-
9. call [`urlEncode`](../dependencies/august/0.19.0/web/contracts.md#symbol-urlEncode) with `input` = `nonce`
|
|
238
|
-
10. `"&code_challenge="`
|
|
239
|
-
11. call [`urlEncode`](../dependencies/august/0.19.0/web/contracts.md#symbol-urlEncode) with `input` = `challenge`
|
|
240
|
-
12. `"&code_challenge_method=S256"`
|
|
241
|
-
- Set `headers` to call [`withCookie`](../common/headers.md#symbol-withCookie) with `headers` = call `with` on call [`securityHeaders`](../common/headers.md#symbol-securityHeaders) with `name` = `"location"`; `value` = `location`; `name` = `"aug_login"`; `value` = `browser`; `path` = `"/login"`; `maxAge` = `300`; `secure` = `secureCookies` of `config`.
|
|
242
|
-
- Return call `HttpResponse` with `body` = the HTML element `p` containing `Opening the identity provider.` (rendered on the server with embedded text escaped); `status` = `303`; `headers` = `headers`.
|
|
243
|
-
|
|
244
|
-
**Author documentation**
|
|
363
|
+
It gets `config` from [`settings`](../common/settings.md#symbol-settings). It gets `document` from [`discover`](protocol.md#symbol-discover) using injected `client`. It sets `browser`, `state`, `nonce`, and `verifier` separately, each to the URL-safe base64 encoding of [`crypto.random`](../dependencies/packages/%40git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/contracts.md#symbol-Crypto.random) with `size` `32`. It sets `transaction` to a [`LoginTransaction`](contracts.md#symbol-LoginTransaction) with `state`, `nonce`, `verifier`, and `expires` from [`clock.now`](../dependencies/packages/%40git/url_c092cd151499c4e1d8a1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.md#symbol-Clock.now) plus `300`.
|
|
245
364
|
|
|
246
|
-
|
|
365
|
+
It calls [`transactions.put`](../dependencies/packages/%40git/url_0eb7c89453c87681ed15/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/store.md#symbol-ExpiringStore.put) with `key` from `browser`, `value` from `transaction`, `transaction.expires`, and `now` from [`clock.now`](../dependencies/packages/%40git/url_c092cd151499c4e1d8a1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.md#symbol-Clock.now). It sets `challenge` to the URL-safe base64 encoding of [`crypto.sha256`](../dependencies/packages/%40git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/contracts.md#symbol-Crypto.sha256) with `input` from the UTF-8 bytes of `verifier`. It builds `location` as the text `{document.authorization_endpoint}?response_type=code&client_id={urlEncode with input from config.clientId}&redirect_uri={urlEncode with input from config.callback}&scope=openid%20profile&state={urlEncode with input from state}&nonce={urlEncode with input from nonce}&code_challenge={urlEncode with input from challenge}&code_challenge_method=S256`. It sets `headers` to [`withCookie`](../common/headers.md#symbol-withCookie) with `headers` from [`securityHeaders`](../common/headers.md#symbol-securityHeaders) with the header `"location"` set to `location`, `name` `"aug_login"`, `value` from `browser`, `path` `"/login"`, `maxAge` `300`, and `secure` from `config.secureCookies`.
|
|
247
366
|
|
|
248
|
-
|
|
367
|
+
It returns HTTP 303 with a paragraph containing `Opening the identity provider.` with escaped text and `headers` headers.
|
|
249
368
|
|
|
250
|
-
[source](login.md#code)
|
|
369
|
+
### `loginCallback` · [source](login.md#code) {#symbol-loginCallback}
|
|
251
370
|
|
|
252
|
-
|
|
371
|
+
`loginCallback` handles `GET /login/callback`. Exchange a one-use code over HTTP, verify the provider JWT/JWKS and UserInfo subject, then issue a distinct app-session JWT.
|
|
253
372
|
|
|
254
|
-
|
|
255
|
-
- `state` (`string`) — read from the HTTP query.
|
|
256
|
-
- `browser` (`optional string`) — read from the HTTP cookie named `aug_login`; absent value becomes null.
|
|
257
|
-
- `crypto` ([`Crypto`](../dependencies/august/0.19.0/crypto/contracts.md#symbol-Crypto)) — injected; callers omit it.
|
|
258
|
-
- `clock` ([`Clock`](../dependencies/august/0.19.0/time/contracts.md#symbol-Clock)) — injected; callers omit it.
|
|
259
|
-
- `client` ([`HttpClient`](../dependencies/august/0.19.0/web/contracts.md#symbol-HttpClient)) — injected; callers omit it.
|
|
260
|
-
- `keys` ([`SigningKeys`](../common/keys.md#symbol-SigningKeys)) — injected; callers omit it.
|
|
261
|
-
- `transactions` ([`ExpiringStore<LoginTransaction>`](../dependencies/august/0.19.0/memory/store.md#symbol-ExpiringStore)) — injected; callers omit it.
|
|
262
|
-
- `sessions` ([`ExpiringStore<SessionClaims>`](../dependencies/august/0.19.0/memory/store.md#symbol-ExpiringStore)) — injected; callers omit it.
|
|
373
|
+
It takes `code` and `state` as strings from the HTTP query and `browser` as `optional string` from the HTTP cookie `aug_login`. It gets `crypto` ([`Crypto`](../dependencies/packages/%40git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/contracts.md#symbol-Crypto)), `clock` ([`Clock`](../dependencies/packages/%40git/url_c092cd151499c4e1d8a1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.md#symbol-Clock)), `client` ([`HttpClient`](../dependencies/packages/%40git/url_897efafd565158fc4908/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.md#symbol-HttpClient)), `keys` ([`SigningKeys`](../common/keys.md#symbol-SigningKeys)), `transactions` ([`ExpiringStore<LoginTransaction>`](../dependencies/packages/%40git/url_0eb7c89453c87681ed15/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/store.md#symbol-ExpiringStore)), and `sessions` ([`ExpiringStore<SessionClaims>`](../dependencies/packages/%40git/url_0eb7c89453c87681ed15/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/store.md#symbol-ExpiringStore)) from dependency injection. Omitted optional inputs are null. The handler responds with HTTP 400 for [`SessionError`](contracts.md#symbol-SessionError), HTTP 503 for `CryptoError`, HTTP 503 for `TimeError`, and HTTP 503 for [`StoreFull`](../dependencies/packages/%40git/url_0eb7c89453c87681ed15/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/store.md#symbol-StoreFull).
|
|
263
374
|
|
|
264
|
-
|
|
375
|
+
It can also raise `HttpError`, `JsonError`, `JwtError`, and `KeyError`.
|
|
265
376
|
|
|
266
|
-
|
|
377
|
+
It checks that `code` is a URL-safe ASCII token with `43` to `43` characters and `state` is a URL-safe ASCII token with `43` to `43` characters. It raises a [`SessionError`](contracts.md#symbol-SessionError) at the first failed check. If `browser` is null, it raises a [`SessionError`](contracts.md#symbol-SessionError). The non-null `browser` becomes `secret`.
|
|
267
378
|
|
|
268
|
-
|
|
379
|
+
It obtains [`transactions.take`](../dependencies/packages/%40git/url_0eb7c89453c87681ed15/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/store.md#symbol-ExpiringStore.take) with `key` from `secret` and `now` from [`clock.now`](../dependencies/packages/%40git/url_c092cd151499c4e1d8a1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.md#symbol-Clock.now). If no value is found, it raises a [`SessionError`](contracts.md#symbol-SessionError). The non-null result becomes `transaction`.
|
|
269
380
|
|
|
270
|
-
|
|
381
|
+
It checks that [`crypto.equal`](../dependencies/packages/%40git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/contracts.md#symbol-Crypto.equal) with `left` from the UTF-8 bytes of `transaction.state` and `right` from the UTF-8 bytes of `state` returns true. It raises a [`SessionError`](contracts.md#symbol-SessionError) at the first failed check. It gets `config` from [`settings`](../common/settings.md#symbol-settings). It gets `document` from [`discover`](protocol.md#symbol-discover) using injected `client`.
|
|
271
382
|
|
|
272
|
-
|
|
383
|
+
It builds `body` as the text `grant_type=authorization_code&code={urlEncode with input from code}&redirect_uri={urlEncode with input from config.callback}&client_id={urlEncode with input from config.clientId}&code_verifier={urlEncode with input from transaction.verifier}`. It sets `headers` to a `Headers` with the header `"content-type"` set to `"application/x-www-form-urlencoded"`. It sets `tokens` to `decode` on [`responseJson`](protocol.md#symbol-responseJson) with `response` from [`client.request`](../dependencies/packages/%40git/url_897efafd565158fc4908/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.md#symbol-HttpClient.request) with `method` `"POST"`, `url` from `document.token_endpoint`, `headers`, and `body` from the UTF-8 bytes of `body` for [`TokenResponse`](../provider/contracts.md#symbol-TokenResponse).
|
|
273
384
|
|
|
274
|
-
|
|
385
|
+
It checks that `tokens.token_type` equals `"Bearer"` and `tokens.access_token` is a URL-safe ASCII token with `43` to `43` characters and `tokens.expires_in` is greater than `0`. It raises a [`SessionError`](contracts.md#symbol-SessionError) at the first failed check. It sets `jwks` to `decode` on [`responseJson`](protocol.md#symbol-responseJson) with `response` from [`client.request`](../dependencies/packages/%40git/url_897efafd565158fc4908/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.md#symbol-HttpClient.request) with `method` `"GET"` and `url` from `document.jwks_uri` for [`RsaJwks`](../dependencies/packages/%40git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/jose.md#symbol-RsaJwks). It sets `identity` to [`validateIdentity`](protocol.md#symbol-validateIdentity) with `token` from `tokens.id_token`, `transaction.nonce`, `now` from [`clock.now`](../dependencies/packages/%40git/url_c092cd151499c4e1d8a1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.md#symbol-Clock.now), and `jwks` using injected `crypto`.
|
|
275
386
|
|
|
276
|
-
|
|
277
|
-
- Fail with call [`SessionError`](contracts.md#symbol-SessionError). Transfer control to a matching catch or propagate the failure.
|
|
278
|
-
- Select the matching case for `browser`:
|
|
279
|
-
- A null value, including omitted optional input:
|
|
280
|
-
- Fail with call [`SessionError`](contracts.md#symbol-SessionError). Transfer control to a matching catch or propagate the failure.
|
|
281
|
-
- A present, non-null value, named `secret`:
|
|
282
|
-
- Select the matching case for call [`ExpiringStore.take`](../dependencies/august/0.19.0/memory/store.md#symbol-ExpiringStore.take) on `transactions` with `key` = `secret`; `now` = call [`Clock.now`](../dependencies/august/0.19.0/time/contracts.md#symbol-Clock.now) on `clock`:
|
|
283
|
-
- A null value, including omitted optional input:
|
|
284
|
-
- Fail with call [`SessionError`](contracts.md#symbol-SessionError). Transfer control to a matching catch or propagate the failure.
|
|
285
|
-
- A present, non-null value, named `transaction`:
|
|
286
|
-
- If not (call [`Crypto.equal`](../dependencies/august/0.19.0/crypto/contracts.md#symbol-Crypto.equal) on `crypto` with `left` = call `bytes` on `state` of `transaction`; `right` = call `bytes` on `state`):
|
|
287
|
-
- Fail with call [`SessionError`](contracts.md#symbol-SessionError). Transfer control to a matching catch or propagate the failure.
|
|
288
|
-
- Set `config` to call [`settings`](../common/settings.md#symbol-settings).
|
|
289
|
-
- Set `document` to call [`discover`](protocol.md#symbol-discover); inject `client` from `client`.
|
|
290
|
-
- Build `body` by joining these text parts without separators, in order:
|
|
291
|
-
1. `"grant_type=authorization_code&code="`
|
|
292
|
-
2. call [`urlEncode`](../dependencies/august/0.19.0/web/contracts.md#symbol-urlEncode) with `input` = `code`
|
|
293
|
-
3. `"&redirect_uri="`
|
|
294
|
-
4. call [`urlEncode`](../dependencies/august/0.19.0/web/contracts.md#symbol-urlEncode) with `input` = `callback` of `config`
|
|
295
|
-
5. `"&client_id="`
|
|
296
|
-
6. call [`urlEncode`](../dependencies/august/0.19.0/web/contracts.md#symbol-urlEncode) with `input` = `clientId` of `config`
|
|
297
|
-
7. `"&code_verifier="`
|
|
298
|
-
8. call [`urlEncode`](../dependencies/august/0.19.0/web/contracts.md#symbol-urlEncode) with `input` = `verifier` of `transaction`
|
|
299
|
-
- Set `headers` to call `with` on call `Headers` with `name` = `"content-type"`; `value` = `"application/x-www-form-urlencoded"`.
|
|
300
|
-
- Set `tokens` to call `decode` on call [`responseJson`](protocol.md#symbol-responseJson) with `response` = call [`HttpClient.request`](../dependencies/august/0.19.0/web/contracts.md#symbol-HttpClient.request) on `client` with `method` = `"POST"`; `url` = `token_endpoint` of `document`; `headers` = `headers`; `body` = call `bytes` on `body` with type arguments [`TokenResponse`](../provider/contracts.md#symbol-TokenResponse).
|
|
301
|
-
- If ((`token_type` of `tokens` does not equal `"Bearer"`) or not (call `isToken` on `access_token` of `tokens` with `min` = `43`; `max` = `43`)) or (`expires_in` of `tokens` is at most `0`):
|
|
302
|
-
- Fail with call [`SessionError`](contracts.md#symbol-SessionError). Transfer control to a matching catch or propagate the failure.
|
|
303
|
-
- Set `jwks` to call `decode` on call [`responseJson`](protocol.md#symbol-responseJson) with `response` = call [`HttpClient.request`](../dependencies/august/0.19.0/web/contracts.md#symbol-HttpClient.request) on `client` with `method` = `"GET"`; `url` = `jwks_uri` of `document` with type arguments [`RsaJwks`](../dependencies/august/0.19.0/crypto/jose.md#symbol-RsaJwks).
|
|
304
|
-
- Set `identity` to call [`validateIdentity`](protocol.md#symbol-validateIdentity) with `token` = `id_token` of `tokens`; `nonce` = `nonce` of `transaction`; `now` = call [`Clock.now`](../dependencies/august/0.19.0/time/contracts.md#symbol-Clock.now) on `clock`; `jwks` = `jwks`; inject `crypto` from `crypto`.
|
|
305
|
-
- Set `authHeaders` to call `with` on call `Headers` with `name` = `"authorization"`; `value` = (`"Bearer "` plus `access_token` of `tokens`).
|
|
306
|
-
- Set `user` to call `decode` on call [`responseJson`](protocol.md#symbol-responseJson) with `response` = call [`HttpClient.request`](../dependencies/august/0.19.0/web/contracts.md#symbol-HttpClient.request) on `client` with `method` = `"GET"`; `url` = `userinfo_endpoint` of `document`; `headers` = `authHeaders` with type arguments [`UserInfo`](../provider/contracts.md#symbol-UserInfo).
|
|
307
|
-
- If `sub` of `user` does not equal `sub` of `identity`:
|
|
308
|
-
- Fail with call [`SessionError`](contracts.md#symbol-SessionError). Transfer control to a matching catch or propagate the failure.
|
|
309
|
-
- Set `now` to call [`Clock.now`](../dependencies/august/0.19.0/time/contracts.md#symbol-Clock.now) on `clock`.
|
|
310
|
-
- Set `session` to call [`SessionClaims`](contracts.md#symbol-SessionClaims) with `iss` = (`baseUrl` of `config` plus `"/app"`); `sub` = `sub` of `identity`; `aud` = `"august-app"`; `exp` = (`now` plus `sessionSeconds` of `config`); `iat` = `now`; `jti` = call `base64url` on call [`Crypto.random`](../dependencies/august/0.19.0/crypto/contracts.md#symbol-Crypto.random) on `crypto` with `size` = `32`; `csrf` = call `base64url` on call [`Crypto.random`](../dependencies/august/0.19.0/crypto/contracts.md#symbol-Crypto.random) on `crypto` with `size` = `32`; `name` = `name` of `user`.
|
|
311
|
-
- Set `jwt` to call [`signJwt`](../dependencies/august/0.19.0/crypto/jose.md#symbol-signJwt) with `key` = call [`SigningKeys.session`](../common/keys.md#symbol-SigningKeys.session) on `keys`; `claims` = call `Json` with `value` = `session`; `kid` = `"session-1"`; `tokenType` = `"august-session+jwt"`; inject `crypto` from `crypto`.
|
|
312
|
-
- Call [`ExpiringStore.put`](../dependencies/august/0.19.0/memory/store.md#symbol-ExpiringStore.put) on `sessions` with `key` = `jti` of `session`; `value` = `session`; `expires` = `exp` of `session`; `now` = `now`.
|
|
313
|
-
- Set `responseHeaders` to call [`withCookie`](../common/headers.md#symbol-withCookie) with `headers` = call `with` on call [`securityHeaders`](../common/headers.md#symbol-securityHeaders) with `name` = `"location"`; `value` = `"/"`; `name` = `"aug_session"`; `value` = `jwt`; `path` = `"/"`; `maxAge` = `sessionSeconds` of `config`; `secure` = `secureCookies` of `config`.
|
|
314
|
-
- Set `responseHeaders` to call [`withCookie`](../common/headers.md#symbol-withCookie) with `headers` = `responseHeaders`; `name` = `"aug_login"`; `value` = `""`; `path` = `"/login"`; `maxAge` = `0`; `secure` = `secureCookies` of `config`.
|
|
315
|
-
- Return call `HttpResponse` with `body` = the HTML element `p` containing `Signed in.` (rendered on the server with embedded text escaped); `status` = `303`; `headers` = `responseHeaders`.
|
|
387
|
+
It sets `authHeaders` to a `Headers` with the header `"authorization"` set to the text `Bearer {tokens.access_token}`. It sets `user` to `decode` on [`responseJson`](protocol.md#symbol-responseJson) with `response` from [`client.request`](../dependencies/packages/%40git/url_897efafd565158fc4908/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.md#symbol-HttpClient.request) with `method` `"GET"`, `url` from `document.userinfo_endpoint`, and `headers` from `authHeaders` for [`UserInfo`](../provider/contracts.md#symbol-UserInfo). It checks that `user.sub` equals `identity.sub`. It raises a [`SessionError`](contracts.md#symbol-SessionError) at the first failed check.
|
|
316
388
|
|
|
317
|
-
|
|
389
|
+
It sets `now` to [`clock.now`](../dependencies/packages/%40git/url_c092cd151499c4e1d8a1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.md#symbol-Clock.now). It sets `session` to a [`SessionClaims`](contracts.md#symbol-SessionClaims) with `iss` from the text `{config.baseUrl}/app`, `identity.sub`, `aud` `"august-app"`, `exp` from `now` plus `config.sessionSeconds`, `iat` from `now`, `jti` from the URL-safe base64 encoding of [`crypto.random`](../dependencies/packages/%40git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/contracts.md#symbol-Crypto.random) with `size` `32`, `csrf` from the URL-safe base64 encoding of [`crypto.random`](../dependencies/packages/%40git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/contracts.md#symbol-Crypto.random) with `size` `32`, and `user.name`. It sets `jwt` to [`signJwt`](../dependencies/packages/%40git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/jose.md#symbol-signJwt) with `key` from [`keys.session`](../common/keys.md#symbol-SigningKeys.session), `claims` from a `Json` with `value` from `session`, `kid` `"session-1"`, and `tokenType` `"august-session+jwt"` using injected `crypto`. It calls [`sessions.put`](../dependencies/packages/%40git/url_0eb7c89453c87681ed15/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/store.md#symbol-ExpiringStore.put) with `key` from `session.jti`, `value` from `session`, `expires` from `session.exp`, and `now`.
|
|
318
390
|
|
|
319
|
-
|
|
391
|
+
It sets `responseHeaders` to [`withCookie`](../common/headers.md#symbol-withCookie) with `headers` from [`securityHeaders`](../common/headers.md#symbol-securityHeaders) with the header `"location"` set to `"/"`, `name` `"aug_session"`, `value` from `jwt`, `path` `"/"`, `maxAge` from `config.sessionSeconds`, and `secure` from `config.secureCookies`. It sets `responseHeaders` to [`withCookie`](../common/headers.md#symbol-withCookie) with `headers` from `responseHeaders`, `name` `"aug_login"`, `value` `""`, `path` `"/login"`, `maxAge` `0`, and `secure` from `config.secureCookies`. It returns HTTP 303 with a paragraph containing `Signed in.` with escaped text and `responseHeaders` headers.
|
|
320
392
|
|
|
321
|
-
### Dependencies
|
|
393
|
+
### Dependencies
|
|
322
394
|
|
|
323
|
-
|
|
395
|
+
It uses [`ExpiringStore`](../dependencies/packages/%40git/url_0eb7c89453c87681ed15/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/store.md#symbol-ExpiringStore) ([`put`](../dependencies/packages/%40git/url_0eb7c89453c87681ed15/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/store.md#symbol-ExpiringStore.put) and [`take`](../dependencies/packages/%40git/url_0eb7c89453c87681ed15/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/store.md#symbol-ExpiringStore.take)) and [`StoreFull`](../dependencies/packages/%40git/url_0eb7c89453c87681ed15/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/store.md#symbol-StoreFull) from `memory`. It uses [`HttpClient`](../dependencies/packages/%40git/url_897efafd565158fc4908/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.md#symbol-HttpClient) ([`request`](../dependencies/packages/%40git/url_897efafd565158fc4908/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.md#symbol-HttpClient.request)) and [`urlEncode`](../dependencies/packages/%40git/url_897efafd565158fc4908/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.md#symbol-urlEncode) from `web`. It uses [`Crypto`](../dependencies/packages/%40git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/contracts.md#symbol-Crypto) ([`decodeBase64url`](../dependencies/packages/%40git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/contracts.md#symbol-Crypto.decodeBase64url), [`equal`](../dependencies/packages/%40git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/contracts.md#symbol-Crypto.equal), [`importRsa`](../dependencies/packages/%40git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/contracts.md#symbol-Crypto.importRsa), [`random`](../dependencies/packages/%40git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/contracts.md#symbol-Crypto.random), [`sha256`](../dependencies/packages/%40git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/contracts.md#symbol-Crypto.sha256), [`signRsa`](../dependencies/packages/%40git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/contracts.md#symbol-Crypto.signRsa), and [`verifyRsa`](../dependencies/packages/%40git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/contracts.md#symbol-Crypto.verifyRsa)), [`JwtError`](../dependencies/packages/%40git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/jose.md#symbol-JwtError), [`RsaJwks`](../dependencies/packages/%40git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/jose.md#symbol-RsaJwks), and [`signJwt`](../dependencies/packages/%40git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/jose.md#symbol-signJwt) from `crypto`. It uses [`Clock`](../dependencies/packages/%40git/url_c092cd151499c4e1d8a1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.md#symbol-Clock) ([`now`](../dependencies/packages/%40git/url_c092cd151499c4e1d8a1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.md#symbol-Clock.now)) from `time`.
|
|
324
396
|
|
|
325
|
-
|
|
397
|
+
It uses [`LoginTransaction`](contracts.md#symbol-LoginTransaction) (`expires`, `nonce`, `state`, and `verifier`), [`SessionClaims`](contracts.md#symbol-SessionClaims) (`exp` and `jti`), and [`SessionError`](contracts.md#symbol-SessionError) from `contracts`. It uses [`discover`](protocol.md#symbol-discover), [`responseJson`](protocol.md#symbol-responseJson), and [`validateIdentity`](protocol.md#symbol-validateIdentity) from `protocol`. It uses [`securityHeaders`](../common/headers.md#symbol-securityHeaders), [`withCookie`](../common/headers.md#symbol-withCookie), [`KeyError`](../common/keys.md#symbol-KeyError), [`SigningKeys`](../common/keys.md#symbol-SigningKeys) ([`session`](../common/keys.md#symbol-SigningKeys.session)), and [`settings`](../common/settings.md#symbol-settings) from `common`. It uses [`Settings`](../common/settings.md#symbol-Settings) (`baseUrl`, `callback`, `clientId`, `secureCookies`, and `sessionSeconds`), [`IdClaims`](../provider/contracts.md#symbol-IdClaims) (`sub`), and [`Discovery`](../provider/discovery.md#symbol-Discovery) (`authorization_endpoint`, `jwks_uri`, `token_endpoint`, and `userinfo_endpoint`).
|
|
326
398
|
|
|
327
|
-
|
|
399
|
+
It uses [`TokenResponse`](../provider/contracts.md#symbol-TokenResponse) (`access_token`, `expires_in`, `id_token`, and `token_type`) and [`UserInfo`](../provider/contracts.md#symbol-UserInfo) (`name` and `sub`) from `provider`.
|
|
328
400
|
|
|
329
|
-
- [
|
|
330
|
-
- [`Crypto.equal`](../dependencies/august/0.19.0/crypto/contracts.md#symbol-Crypto.equal) (`left`: `Bytes`, `right`: `Bytes`) → `bool`.
|
|
331
|
-
- [`Crypto.importRsa`](../dependencies/august/0.19.0/crypto/contracts.md#symbol-Crypto.importRsa) (`modulus`: `Bytes`, `exponent`: `Bytes`) → `RsaPublicKey`; can fail with `CryptoError`.
|
|
332
|
-
- [`Crypto.random`](../dependencies/august/0.19.0/crypto/contracts.md#symbol-Crypto.random) (`size`: `int`) → `Bytes`; can fail with `CryptoError`.
|
|
333
|
-
- [`Crypto.sha256`](../dependencies/august/0.19.0/crypto/contracts.md#symbol-Crypto.sha256) (`input`: `Bytes`) → `Bytes`; can fail with `CryptoError`.
|
|
334
|
-
- [`Crypto.signRsa`](../dependencies/august/0.19.0/crypto/contracts.md#symbol-Crypto.signRsa) (`key`: `RsaPrivateKey`, `input`: `Bytes`) → `Bytes`; can fail with `CryptoError`.
|
|
335
|
-
- [`Crypto.verifyRsa`](../dependencies/august/0.19.0/crypto/contracts.md#symbol-Crypto.verifyRsa) (`publicKey`: `RsaPublicKey`, `input`: `Bytes`, `signature`: `Bytes`) → `bool`; can fail with `CryptoError`.
|
|
336
|
-
|
|
337
|
-
#### [`JwtError`](../dependencies/august/0.19.0/crypto/jose.md#symbol-JwtError)
|
|
338
|
-
|
|
339
|
-
Class from `august.crypto`.
|
|
340
|
-
|
|
341
|
-
Used as a type or provider.
|
|
342
|
-
|
|
343
|
-
#### [`RsaJwks`](../dependencies/august/0.19.0/crypto/jose.md#symbol-RsaJwks)
|
|
344
|
-
|
|
345
|
-
Record from `august.crypto`.
|
|
346
|
-
|
|
347
|
-
Used as a type or provider.
|
|
348
|
-
|
|
349
|
-
#### [`signJwt`](../dependencies/august/0.19.0/crypto/jose.md#symbol-signJwt)
|
|
350
|
-
|
|
351
|
-
Function from `august.crypto`.
|
|
352
|
-
|
|
353
|
-
- [`signJwt`](../dependencies/august/0.19.0/crypto/jose.md#symbol-signJwt) (`key`: `RsaPrivateKey`, `claims`: `Json`, `kid`: `string`, `tokenType`: `string`) → `string`; inject `crypto`: [`Crypto`](../dependencies/august/0.19.0/crypto/contracts.md#symbol-Crypto); uses [`crypto.signRsa`](../dependencies/august/0.19.0/crypto/contracts.md#symbol-Crypto.signRsa); can fail with `JwtError`.
|
|
354
|
-
|
|
355
|
-
#### [`ExpiringStore`](../dependencies/august/0.19.0/memory/store.md#symbol-ExpiringStore)
|
|
356
|
-
|
|
357
|
-
Capability interface from `august.memory`.
|
|
358
|
-
|
|
359
|
-
- [`ExpiringStore.put`](../dependencies/august/0.19.0/memory/store.md#symbol-ExpiringStore.put) (`key`: `string`, `value`: `T`, `expires`: `int`, `now`: `int`) → `void`; can fail with `StoreFull`.
|
|
360
|
-
- [`ExpiringStore.take`](../dependencies/august/0.19.0/memory/store.md#symbol-ExpiringStore.take) (`key`: `string`, `now`: `int`) → `optional T`.
|
|
361
|
-
|
|
362
|
-
#### [`StoreFull`](../dependencies/august/0.19.0/memory/store.md#symbol-StoreFull)
|
|
363
|
-
|
|
364
|
-
Class from `august.memory`.
|
|
365
|
-
|
|
366
|
-
Used as a type or provider.
|
|
367
|
-
|
|
368
|
-
#### [`Clock`](../dependencies/august/0.19.0/time/contracts.md#symbol-Clock)
|
|
369
|
-
|
|
370
|
-
Capability interface from `august.time`.
|
|
371
|
-
|
|
372
|
-
- [`Clock.now`](../dependencies/august/0.19.0/time/contracts.md#symbol-Clock.now) (no caller inputs) → `int`; can fail with `TimeError`.
|
|
373
|
-
|
|
374
|
-
#### [`HttpClient`](../dependencies/august/0.19.0/web/contracts.md#symbol-HttpClient)
|
|
375
|
-
|
|
376
|
-
Capability interface from `august.web`.
|
|
377
|
-
|
|
378
|
-
- [`HttpClient.request`](../dependencies/august/0.19.0/web/contracts.md#symbol-HttpClient.request) (`method`: `string`, `url`: `string`, `headers`: `optional Headers`, `body`: `optional Bytes`) → `HttpResponse<Bytes>`; can fail with `HttpError`.
|
|
379
|
-
|
|
380
|
-
#### [`urlEncode`](../dependencies/august/0.19.0/web/contracts.md#symbol-urlEncode)
|
|
381
|
-
|
|
382
|
-
Function from `august.web`.
|
|
383
|
-
|
|
384
|
-
- [`urlEncode`](../dependencies/august/0.19.0/web/contracts.md#symbol-urlEncode) (`input`: `string`) → `string`; can fail with `HttpError`.
|
|
385
|
-
|
|
386
|
-
#### [`LoginTransaction`](contracts.md#symbol-LoginTransaction)
|
|
387
|
-
|
|
388
|
-
Record from `contracts`.
|
|
389
|
-
|
|
390
|
-
- Construct with `state`: `string`, `nonce`: `string`, `verifier`: `string`, `expires`: `int` → [`LoginTransaction`](contracts.md#symbol-LoginTransaction).
|
|
391
|
-
- Read `expires` (`int`).
|
|
392
|
-
- Read `nonce` (`string`).
|
|
393
|
-
- Read `state` (`string`).
|
|
394
|
-
- Read `verifier` (`string`).
|
|
395
|
-
|
|
396
|
-
#### [`SessionClaims`](contracts.md#symbol-SessionClaims)
|
|
397
|
-
|
|
398
|
-
Record from `contracts`.
|
|
399
|
-
|
|
400
|
-
- Construct with `iss`: `string`, `sub`: `string`, `aud`: `string`, `exp`: `int`, `iat`: `int`, `jti`: `string`, `csrf`: `string`, `name`: `string` → [`SessionClaims`](contracts.md#symbol-SessionClaims).
|
|
401
|
-
- Read `exp` (`int`).
|
|
402
|
-
- Read `jti` (`string`).
|
|
403
|
-
|
|
404
|
-
#### [`SessionError`](contracts.md#symbol-SessionError)
|
|
405
|
-
|
|
406
|
-
Class from `contracts`.
|
|
407
|
-
|
|
408
|
-
- Construct with no caller inputs → [`SessionError`](contracts.md#symbol-SessionError).
|
|
409
|
-
|
|
410
|
-
#### [`discover`](protocol.md#symbol-discover)
|
|
411
|
-
|
|
412
|
-
Function from `protocol`.
|
|
413
|
-
|
|
414
|
-
- [`discover`](protocol.md#symbol-discover) (no caller inputs) → [`Discovery`](../provider/discovery.md#symbol-Discovery); inject `client`: [`HttpClient`](../dependencies/august/0.19.0/web/contracts.md#symbol-HttpClient); uses [`client.request`](../dependencies/august/0.19.0/web/contracts.md#symbol-HttpClient.request); can fail with `SessionError`, `HttpError`.
|
|
415
|
-
|
|
416
|
-
#### [`responseJson`](protocol.md#symbol-responseJson)
|
|
417
|
-
|
|
418
|
-
Function from `protocol`.
|
|
419
|
-
|
|
420
|
-
- [`responseJson`](protocol.md#symbol-responseJson) (`response`: `HttpResponse<Bytes>`) → `Json`; can fail with `SessionError`.
|
|
421
|
-
|
|
422
|
-
#### [`validateIdentity`](protocol.md#symbol-validateIdentity)
|
|
423
|
-
|
|
424
|
-
Function from `protocol`.
|
|
425
|
-
|
|
426
|
-
- [`validateIdentity`](protocol.md#symbol-validateIdentity) (`token`: `string`, `nonce`: `string`, `now`: `int`, `jwks`: [`RsaJwks`](../dependencies/august/0.19.0/crypto/jose.md#symbol-RsaJwks)) → [`IdClaims`](../provider/contracts.md#symbol-IdClaims); inject `crypto`: [`Crypto`](../dependencies/august/0.19.0/crypto/contracts.md#symbol-Crypto); uses [`crypto.decodeBase64url`](../dependencies/august/0.19.0/crypto/contracts.md#symbol-Crypto.decodeBase64url), [`crypto.importRsa`](../dependencies/august/0.19.0/crypto/contracts.md#symbol-Crypto.importRsa), [`crypto.verifyRsa`](../dependencies/august/0.19.0/crypto/contracts.md#symbol-Crypto.verifyRsa), [`crypto.equal`](../dependencies/august/0.19.0/crypto/contracts.md#symbol-Crypto.equal); can fail with `SessionError`.
|
|
427
|
-
|
|
428
|
-
#### [`securityHeaders`](../common/headers.md#symbol-securityHeaders)
|
|
429
|
-
|
|
430
|
-
Function from `common`.
|
|
431
|
-
|
|
432
|
-
- [`securityHeaders`](../common/headers.md#symbol-securityHeaders) (no caller inputs) → `Headers`; can fail with `HttpError`.
|
|
433
|
-
|
|
434
|
-
#### [`withCookie`](../common/headers.md#symbol-withCookie)
|
|
435
|
-
|
|
436
|
-
Function from `common`.
|
|
437
|
-
|
|
438
|
-
- [`withCookie`](../common/headers.md#symbol-withCookie) (`headers`: `Headers`, `name`: `string`, `value`: `string`, `path`: `string`, `maxAge`: `int`, `secure`: `bool`) → `Headers`; can fail with `HttpError`.
|
|
439
|
-
|
|
440
|
-
#### [`KeyError`](../common/keys.md#symbol-KeyError)
|
|
441
|
-
|
|
442
|
-
Class from `common`.
|
|
443
|
-
|
|
444
|
-
Used as a type or provider.
|
|
445
|
-
|
|
446
|
-
#### [`SigningKeys`](../common/keys.md#symbol-SigningKeys)
|
|
447
|
-
|
|
448
|
-
Capability interface from `common`.
|
|
449
|
-
|
|
450
|
-
- [`SigningKeys.session`](../common/keys.md#symbol-SigningKeys.session) (no caller inputs) → `RsaPrivateKey`; can fail with `KeyError`.
|
|
451
|
-
|
|
452
|
-
#### [`Settings`](../common/settings.md#symbol-Settings)
|
|
453
|
-
|
|
454
|
-
Record.
|
|
455
|
-
|
|
456
|
-
- Read `baseUrl` (`string`).
|
|
457
|
-
- Read `callback` (`string`).
|
|
458
|
-
- Read `clientId` (`string`).
|
|
459
|
-
- Read `secureCookies` (`bool`).
|
|
460
|
-
- Read `sessionSeconds` (`int`).
|
|
461
|
-
|
|
462
|
-
#### [`settings`](../common/settings.md#symbol-settings)
|
|
463
|
-
|
|
464
|
-
Function from `common`.
|
|
465
|
-
|
|
466
|
-
- [`settings`](../common/settings.md#symbol-settings) (no caller inputs) → [`Settings`](../common/settings.md#symbol-Settings).
|
|
467
|
-
|
|
468
|
-
#### [`IdClaims`](../provider/contracts.md#symbol-IdClaims)
|
|
469
|
-
|
|
470
|
-
Record.
|
|
471
|
-
|
|
472
|
-
- Read `sub` (`string`).
|
|
473
|
-
|
|
474
|
-
#### [`TokenResponse`](../provider/contracts.md#symbol-TokenResponse)
|
|
475
|
-
|
|
476
|
-
Record from `provider`.
|
|
477
|
-
|
|
478
|
-
- Read `access_token` (`string`).
|
|
479
|
-
- Read `expires_in` (`int`).
|
|
480
|
-
- Read `id_token` (`string`).
|
|
481
|
-
- Read `token_type` (`string`).
|
|
482
|
-
|
|
483
|
-
#### [`UserInfo`](../provider/contracts.md#symbol-UserInfo)
|
|
484
|
-
|
|
485
|
-
Record from `provider`.
|
|
486
|
-
|
|
487
|
-
- Read `name` (`string`).
|
|
488
|
-
- Read `sub` (`string`).
|
|
489
|
-
|
|
490
|
-
#### [`Discovery`](../provider/discovery.md#symbol-Discovery)
|
|
491
|
-
|
|
492
|
-
Record.
|
|
493
|
-
|
|
494
|
-
- Read `authorization_endpoint` (`string`).
|
|
495
|
-
- Read `jwks_uri` (`string`).
|
|
496
|
-
- Read `token_endpoint` (`string`).
|
|
497
|
-
- Read `userinfo_endpoint` (`string`).
|
|
498
|
-
|
|
499
|
-
### Built-in operations used by this file
|
|
500
|
-
|
|
501
|
-
- `Bytes.base64url` (no inputs) → `string`: Encode immutable bytes as unpadded RFC 4648 URL-safe base64.
|
|
502
|
-
- `Headers.with` (`name`: `string`, `value`: `string`) → `Headers`: Return new headers with one additional validated field. Header names ignore case; duplicate values remain separate. Can fail with `HttpError`.
|
|
503
|
-
- `Json.decode` (no inputs) → `UserInfo`: Decode a checked record or data type: json.decode<Profile>(). Unknown fields, type mismatches, and validation errors are rejected. Can fail with `JsonError`.
|
|
504
|
-
- `string.bytes` (no inputs) → `Bytes`: Encode this string as immutable UTF-8 bytes.
|
|
505
|
-
- `string.isToken` (`min`: `int`, `max`: `int`) → `bool`: Require an ASCII RFC 3986 unreserved token with a bounded length.
|
|
506
|
-
|
|
507
|
-
[Full built-in reference](https://greenpandastudios.github.io/augscript/language-constructs).
|
|
508
|
-
|
|
509
|
-
### Shared language rules
|
|
510
|
-
|
|
511
|
-
See the [language reference](https://greenpandastudios.github.io/augscript/reference) for numeric, equality, ownership, and task rules.
|
|
401
|
+
Built-in operations follow the [language reference](https://greenpandastudios.github.io/augscript/language-constructs).
|
|
512
402
|
|
|
513
403
|
::::
|
|
514
404
|
|