diff --git a/.dockerignore b/.dockerignore index 5d4e0f6ced..0fea514232 100644 --- a/.dockerignore +++ b/.dockerignore @@ -7,6 +7,7 @@ /k8s/ /node_modules/ /console/src/app/proto/generated/ +/console/.angular /console/tmp/ .releaserc.js changelog.config.js @@ -18,3 +19,4 @@ pkg/grpc/*/*.pb.* pkg/grpc/*/*.swagger.json .goreleaser.yaml .artifacts/ +.vscode diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index b59ca669c3..899ab5a036 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -7,6 +7,7 @@ - [ ] All open todos and follow ups are defined in a new ticket and justified - [ ] Deviations from the acceptance criteria and design are agreed with the PO and documented. - [ ] No debug or dead code +- [ ] My code has no repetitions - [ ] Critical parts are tested automatically - [ ] Where possible E2E tests are implemented - [ ] Documentation/examples are up-to-date diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 8f7ba48a11..2347e029ad 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -43,7 +43,7 @@ jobs: go run main.go init --config internal/integration/config/zitadel.yaml --config internal/integration/config/${INTEGRATION_DB_FLAVOR}.yaml go run main.go setup --masterkeyFromEnv --config internal/integration/config/zitadel.yaml --config internal/integration/config/${INTEGRATION_DB_FLAVOR}.yaml - name: Run integration tests - run: go test -tags=integration -race -parallel 1 -v -coverprofile=profile.cov -coverpkg=./... ./internal/integration ./internal/api/grpc/... + run: go test -tags=integration -race -parallel 1 -v -coverprofile=profile.cov -coverpkg=./internal/...,./cmd/... ./internal/integration ./internal/api/grpc/... - name: Publish go coverage uses: codecov/codecov-action@v3.1.0 with: diff --git a/.github/workflows/zitadel.yml b/.github/workflows/zitadel.yml index 2691109f80..c5512d5290 100644 --- a/.github/workflows/zitadel.yml +++ b/.github/workflows/zitadel.yml @@ -80,7 +80,7 @@ jobs: name: go-codecov - name: Bump Chart Version uses: peter-evans/repository-dispatch@v2 - if: steps.semantic.outputs.new_release_published == 'true' && github.ref == 'refs/heads/main' + if: steps.semantic.outputs.new_release_published == 'true' && github.ref == 'refs/heads/next' with: token: ${{ steps.generate-token.outputs.token }} repository: zitadel/zitadel-charts diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 87ecad547e..bdbad1f5a5 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -18,6 +18,7 @@ before: - docker build -f build/grpc/Dockerfile -t zitadel-base:local . - docker build -f build/zitadel/Dockerfile . -t zitadel-go-test --target go-codecov -o .artifacts/codecov - docker build -f build/zitadel/Dockerfile . -t zitadel-go-base --target go-copy -o .artifacts/grpc/go-client + - sh -c "find pkg/grpc -name '*.pb*.go' -delete" - sh -c "cp -r .artifacts/grpc/go-client/* ." - docker build -f build/console/Dockerfile . -t zitadel-npm-console --target angular-export -o .artifacts/console - sh -c "cp -r .artifacts/console/* internal/api/ui/console/static/" diff --git a/.releaserc.js b/.releaserc.js index f24249cada..2103f3f3de 100644 --- a/.releaserc.js +++ b/.releaserc.js @@ -1,7 +1,8 @@ module.exports = { branches: [ - {name: 'main'}, - {name: 'next'}, + { name: 'main' }, + { name: 'next' }, + { name: 'rc', prerelease: true }, ], plugins: [ "@semantic-release/commit-analyzer" diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6d35289418..00238fd516 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -36,7 +36,7 @@ We strongly recommend to [talk to us](https://zitadel.com/contact) before you st We accept contributions through pull requests. You need a github account for that. If you are unfamiliar with git have a look at Github's documentation on [creating forks](https://help.github.com/articles/fork-a-repo) and [creating pull requests](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork). Please draft the pull request as soon as possible. Go through the following checklist before you submit the final pull request: -### Submit a Pull Request (PR) +### Submit a pull request (PR) 1. [Fork](https://docs.github.com/en/get-started/quickstart/fork-a-repo) the [zitadel/zitadel](https://github.com/zitadel/zitadel) repository on GitHub 2. On your fork, commit your changes to a new branch @@ -59,14 +59,14 @@ We accept contributions through pull requests. You need a github account for tha 8. On GitHub, [send a pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/requesting-a-pull-request-review) to `zitadel:main`. Request review from one of the maintainers. -### Reviewing a Pull Request +### Review a pull request The reviewers will provide you feedback and approve your changes as soon as they are satisfied. If we ask you for changes in the code, you can follow the [GitHub Guide](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/incorporating-feedback-in-your-pull-request) to incorporate feedback in your pull request. -### Commit Messages +### Commit messages Make sure you use [semantic release messages format](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#type). @@ -84,7 +84,7 @@ Must be one of the following: This is optional to indicate which component is affected. In doubt, leave blank (`: `) -#### Short Summary +#### Short summary Provide a brief description of the change. @@ -107,7 +107,7 @@ We add the label "good first issue" for problems we think are a good starting po - [Issues for first time contributors](https://github.com/zitadel/zitadel/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) - [All issues](https://github.com/zitadel/zitadel/issues) -### Backend / Login +### Backend/login By executing the commands from this section, you run everything you need to develop the ZITADEL backend locally. Using [Docker Compose](https://docs.docker.com/compose/), you run a [CockroachDB](https://www.cockroachlabs.com/docs/stable/start-a-local-cluster-in-docker-mac.html) on your local machine. @@ -231,7 +231,6 @@ The commands in this section are tested against the following software versions: - [Node version v16.17.0](https://nodejs.org/en/download/) - [npm version 8.18.0](https://docs.npmjs.com/try-the-latest-stable-version-of-npm) - [Cypress runtime dependencies](https://docs.cypress.io/guides/continuous-integration/introduction#Dependencies) -- [curl version 7.58.0](https://curl.se/download.html)
Note for WSL2 on Windows 10 @@ -269,18 +268,17 @@ To allow console access via http://localhost:4200, you have to configure the ZIT You can run the local console development server now. ```bash -# Console loads its target environment from the file console/src/assets/environment.json. -# Load it from the backend. -curl http://localhost:8080/ui/console/assets/environment.json > ./src/assets/environment.json +# Install npm dependencies +npm install # Generate source files from Protos npm run generate -# Install npm dependencies -npm install - # Start the server npm start + +# If you don't want to develop against http://localhost:8080, you can use another environment +ENVIRONMENT_JSON_URL=https://my-cloud-instance-abcdef.zitadel.cloud/ui/console/assets/environment.json npm start ``` Navigate to http://localhost:4200/. @@ -326,25 +324,36 @@ When you are happy with your changes, you can format your code and cleanup your docker compose down ``` -## Contribute Docs +## Contribute docs Project documentation is made with docusaurus and is located under [./docs](./docs). -### Local Testing +### Local testing Please refer to the [README](./docs/README.md) for more information and local testing. -### Style Guide +### Style guide - **Code with variables**: Make sure that code snippets can be used by setting environment variables, instead of manually replacing a placeholder. - **Embedded files**: When embedding mdx files, make sure the template ist prefixed by "_" (lowdash). The content will be rendered inside the parent page, but is not accessible individually (eg, by search). +- **Don't repeat yourself**: When using the same content in multiple places, save and manage the content as separate file and make use of embedded files to import it into other docs pages. - **Embedded code**: You can embed code snippets from a repository. See the [plugin](https://github.com/saucelabs/docusaurus-theme-github-codeblock#usage) for usage. -### Docs Pull Request +Following the [Google style guide](https://developers.google.com/style) is highly recommended. Its clear and concise guidelines ensure consistency and effective communication within the wider developer community. + +The style guide covers a lot of material, so their [highlights](https://developers.google.com/style/highlights) page provides an overview of its most important points. Some of the points stated in the highlights that we care about most are given below: + +- Be conversational and friendly without being frivolous. +- Use sentence case for document titles and section headings. +- Use active voice: make clear who's performing the action. +- Use descriptive link text. + +### Docs pull request + When making a pull request use `docs(): ` as title for the semantic release. Scope can be left empty (omit the brackets) or refer to the top navigation sections. -## Contribute Internationalization +## Contribute internationalization ZITADEL loads translations from four files: @@ -364,7 +373,7 @@ You can find an installation guide for all the different environments here: - Please read [Security Policy](./SECURITY.md). -## Product Management +## Product management The ZITADEL Team works with an agile product management methodology. You can find all the issues prioritized and ordered in the [product board](https://github.com/orgs/zitadel/projects/2/views/1). @@ -388,10 +397,10 @@ The state should reflect the progress of the issue and what is going on right no - **No status**: Issue just got added and has to be looked at. - **🧐 Investigating**: We are currently investigating to find out what the problem is, which priority it should have and what has to be implemented. Or we need some more information from the author. -- **📨 Product Backlog**: If an issue is in the backlog, it is not currently being worked on. These are recorded so that they can be worked on in the future. Issues with this state do not have to be completely defined yet. -- **📝 Prioritized Product Backlog**: An issue with the state "Prioritized Backlog" is ready for the refinement from the perspective of the product owner (PO) to implement. This means the developer can find all the relevant information and acceptance criteria in the issue. +- **📨 Product backlog**: If an issue is in the backlog, it is not currently being worked on. These are recorded so that they can be worked on in the future. Issues with this state do not have to be completely defined yet. +- **📝 Prioritized product backlog**: An issue with the state "Prioritized Backlog" is ready for the refinement from the perspective of the product owner (PO) to implement. This means the developer can find all the relevant information and acceptance criteria in the issue. - **🔖 Ready**: The issue is ready to take into a sprint. Difference to "prioritized..." is that the complexity is defined by the team. -- **📋 Sprint Backlog**: The issue is scheduled for the current sprint. +- **📋 Sprint backlog**: The issue is scheduled for the current sprint. - **🏗 In progress**: Someone is working on this issue right now. The issue will get an assignee as soon as it is in progress. - **👀 In review**: The issue is in review. Please add someone to review your issue or let us know that it is ready to review with a comment on your pull request. - **✅ Done**: The issue is implemented and merged to main. @@ -413,7 +422,7 @@ Everything that is higher than 8 should be split in smaller parts. **1**, **2**, **3**, **5**, **8**, **13** -### About the Labels +### About the labels There are a few general labels that don't belong to a specific category. diff --git a/README.md b/README.md index 18c9ae3e4a..bfabb60be5 100644 --- a/README.md +++ b/README.md @@ -94,7 +94,7 @@ Authentication - Single Sign On (SSO) - Passwordless with FIDO2 support (Including Passkeys) - Username / Password -- Multifactor authentication with OTP, U2F, SMS +- Multifactor authentication with OTP, U2F - LDAP - [OpenID Connect certified](https://openid.net/certification/#OPs) => [OIDC Endpoints](https://zitadel.com/docs/apis/openidoauth/endpoints) - [SAML 2.0](http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0.html) => [SAML Endpoints](https://zitadel.com/docs/apis/saml/endpoints) diff --git a/cmd/defaults.yaml b/cmd/defaults.yaml index 0867a1d5d3..4cc990b34b 100644 --- a/cmd/defaults.yaml +++ b/cmd/defaults.yaml @@ -735,6 +735,7 @@ InternalAuthZ: - "user.grant.delete" - "user.membership.read" - "user.credential.write" + - "user.passkey.write" - "policy.read" - "policy.write" - "policy.delete" @@ -811,6 +812,7 @@ InternalAuthZ: - "user.grant.delete" - "user.membership.read" - "user.credential.write" + - "user.passkey.write" - "policy.read" - "policy.write" - "policy.delete" @@ -847,6 +849,7 @@ InternalAuthZ: - "user.grant.write" - "user.grant.delete" - "user.membership.read" + - "user.passkey.write" - "project.read" - "project.member.read" - "project.role.read" @@ -882,6 +885,7 @@ InternalAuthZ: - "user.grant.delete" - "user.membership.read" - "user.credential.write" + - "user.passkey.write" - "policy.read" - "policy.write" - "policy.delete" diff --git a/cmd/setup/10.go b/cmd/setup/10.go index fd8683f49d..1661ccf7dd 100644 --- a/cmd/setup/10.go +++ b/cmd/setup/10.go @@ -13,11 +13,11 @@ import ( ) var ( - //go:embed 10_create_temp_table.sql + //go:embed 10/10_create_temp_table.sql correctCreationDate10CreateTable string - //go:embed 10_fill_table.sql + //go:embed 10/10_fill_table.sql correctCreationDate10FillTable string - //go:embed 10_update.sql + //go:embed 10/10_update.sql correctCreationDate10Update string ) diff --git a/cmd/setup/10_create_temp_table.sql b/cmd/setup/10/10_create_temp_table.sql similarity index 100% rename from cmd/setup/10_create_temp_table.sql rename to cmd/setup/10/10_create_temp_table.sql diff --git a/cmd/setup/10_fill_table.sql b/cmd/setup/10/10_fill_table.sql similarity index 100% rename from cmd/setup/10_fill_table.sql rename to cmd/setup/10/10_fill_table.sql diff --git a/cmd/setup/10_update.sql b/cmd/setup/10/10_update.sql similarity index 100% rename from cmd/setup/10_update.sql rename to cmd/setup/10/10_update.sql diff --git a/cmd/setup/11.go b/cmd/setup/11.go new file mode 100644 index 0000000000..4745c71994 --- /dev/null +++ b/cmd/setup/11.go @@ -0,0 +1,32 @@ +package setup + +import ( + "context" + _ "embed" + + "github.com/zitadel/zitadel/internal/database" +) + +var ( + //go:embed 11.sql + addEventCreatedAt string +) + +type AddEventCreatedAt struct { + step10 *CorrectCreationDate + dbClient *database.DB +} + +func (mig *AddEventCreatedAt) Execute(ctx context.Context) error { + // execute step 10 again because events created after the first execution of step 10 + // could still have the wrong ordering of sequences and creation date + if err := mig.step10.Execute(ctx); err != nil { + return err + } + _, err := mig.dbClient.ExecContext(ctx, addEventCreatedAt) + return err +} + +func (mig *AddEventCreatedAt) String() string { + return "11_event_created_at" +} diff --git a/cmd/setup/11.sql b/cmd/setup/11.sql new file mode 100644 index 0000000000..bb62b5f9b2 --- /dev/null +++ b/cmd/setup/11.sql @@ -0,0 +1,15 @@ +BEGIN; +-- create table with empty created_at +ALTER TABLE eventstore.events ADD COLUMN created_at TIMESTAMPTZ DEFAULT NULL; +COMMIT; + +BEGIN; +-- backfill created_at +UPDATE eventstore.events SET created_at = creation_date WHERE created_at IS NULL; +COMMIT; + +BEGIN; +-- set column rules +ALTER TABLE eventstore.events ALTER COLUMN created_at SET DEFAULT clock_timestamp(); +ALTER TABLE eventstore.events ALTER COLUMN created_at SET NOT NULL; +COMMIT; \ No newline at end of file diff --git a/cmd/setup/config.go b/cmd/setup/config.go index dc75d54048..5e9819e4c7 100644 --- a/cmd/setup/config.go +++ b/cmd/setup/config.go @@ -66,6 +66,7 @@ type Steps struct { s8AuthTokens *AuthTokenIndexes s9EventstoreIndexes2 *EventstoreIndexesNew CorrectCreationDate *CorrectCreationDate + s11AddEventCreatedAt *AddEventCreatedAt } type encryptionKeyConfig struct { diff --git a/cmd/setup/setup.go b/cmd/setup/setup.go index 918f08dc2d..59b7c5d6ba 100644 --- a/cmd/setup/setup.go +++ b/cmd/setup/setup.go @@ -91,6 +91,7 @@ func Setup(config *Config, steps *Steps, masterKey string) { steps.s8AuthTokens = &AuthTokenIndexes{dbClient: dbClient} steps.s9EventstoreIndexes2 = New09(dbClient) steps.CorrectCreationDate.dbClient = dbClient + steps.s11AddEventCreatedAt = &AddEventCreatedAt{dbClient: dbClient, step10: steps.CorrectCreationDate} err = projection.Create(ctx, dbClient, eventstoreClient, config.Projections, nil, nil) logging.OnError(err).Fatal("unable to start projections") @@ -128,6 +129,8 @@ func Setup(config *Config, steps *Steps, masterKey string) { logging.OnError(err).Fatal("unable to migrate step 9") err = migration.Migrate(ctx, eventstoreClient, steps.CorrectCreationDate) logging.OnError(err).Fatal("unable to migrate step 10") + err = migration.Migrate(ctx, eventstoreClient, steps.s11AddEventCreatedAt) + logging.OnError(err).Fatal("unable to migrate step 11") for _, repeatableStep := range repeatableSteps { err = migration.Migrate(ctx, eventstoreClient, repeatableStep) diff --git a/cmd/start/start.go b/cmd/start/start.go index 0d2d973690..75516fba4d 100644 --- a/cmd/start/start.go +++ b/cmd/start/start.go @@ -38,6 +38,7 @@ import ( "github.com/zitadel/zitadel/internal/api/grpc/user/v2" http_util "github.com/zitadel/zitadel/internal/api/http" "github.com/zitadel/zitadel/internal/api/http/middleware" + "github.com/zitadel/zitadel/internal/api/idp" "github.com/zitadel/zitadel/internal/api/oidc" "github.com/zitadel/zitadel/internal/api/robots_txt" "github.com/zitadel/zitadel/internal/api/saml" @@ -306,9 +307,8 @@ func startAPIs( http_util.WithNonHttpOnly(), http_util.WithMaxAge(int(math.Floor(config.Quotas.Access.ExhaustedCookieMaxAge.Seconds()))), ) - limitingAccessInterceptor := middleware.NewAccessInterceptor(accessSvc, exhaustedCookieHandler, config.Quotas.Access, false) - nonLimitingAccessInterceptor := middleware.NewAccessInterceptor(accessSvc, nil, config.Quotas.Access, true) - apis, err := api.New(ctx, config.Port, router, queries, verifier, config.InternalAuthZ, tlsConfig, config.HTTP2HostHeader, config.HTTP1HostHeader, accessSvc, exhaustedCookieHandler, config.Quotas.Access) + limitingAccessInterceptor := middleware.NewAccessInterceptor(accessSvc, exhaustedCookieHandler, config.Quotas.Access) + apis, err := api.New(ctx, config.Port, router, queries, verifier, config.InternalAuthZ, tlsConfig, config.HTTP2HostHeader, config.HTTP1HostHeader, limitingAccessInterceptor) if err != nil { return fmt.Errorf("error creating api %w", err) } @@ -332,7 +332,7 @@ func startAPIs( if err := apis.RegisterServer(ctx, auth.CreateServer(commands, queries, authRepo, config.SystemDefaults, keys.User, config.ExternalSecure, config.AuditLogRetention)); err != nil { return err } - if err := apis.RegisterService(ctx, user.CreateServer(commands, queries, keys.User)); err != nil { + if err := apis.RegisterService(ctx, user.CreateServer(commands, queries, keys.User, keys.IDPConfig, idp.CallbackURL(config.ExternalSecure))); err != nil { return err } if err := apis.RegisterService(ctx, session.CreateServer(commands, queries, permissionCheck)); err != nil { @@ -345,6 +345,8 @@ func startAPIs( assetsCache := middleware.AssetsCacheInterceptor(config.AssetStorage.Cache.MaxAge, config.AssetStorage.Cache.SharedMaxAge) apis.RegisterHandlerOnPrefix(assets.HandlerPrefix, assets.NewHandler(commands, verifier, config.InternalAuthZ, id.SonyFlakeGenerator(), store, queries, middleware.CallDurationHandler, instanceInterceptor.Handler, assetsCache.Handler, limitingAccessInterceptor.Handle)) + apis.RegisterHandlerOnPrefix(idp.HandlerPrefix, idp.NewHandler(commands, queries, keys.IDPConfig, config.ExternalSecure, instanceInterceptor.Handler)) + userAgentInterceptor, err := middleware.NewUserAgentHandler(config.UserAgentCookie, keys.UserAgentCookieKey, id.SonyFlakeGenerator(), config.ExternalSecure, login.EndpointResources) if err != nil { return err @@ -376,7 +378,7 @@ func startAPIs( } apis.RegisterHandlerOnPrefix(saml.HandlerPrefix, samlProvider.HttpHandler()) - c, err := console.Start(config.Console, config.ExternalSecure, oidcProvider.IssuerFromRequest, middleware.CallDurationHandler, instanceInterceptor.Handler, nonLimitingAccessInterceptor.Handle, config.CustomerPortal) + c, err := console.Start(config.Console, config.ExternalSecure, oidcProvider.IssuerFromRequest, middleware.CallDurationHandler, instanceInterceptor.Handler, limitingAccessInterceptor, config.CustomerPortal) if err != nil { return fmt.Errorf("unable to start console: %w", err) } diff --git a/console/angular.json b/console/angular.json index 88d43181d2..03ab02ddfc 100644 --- a/console/angular.json +++ b/console/angular.json @@ -35,7 +35,8 @@ "codemirror/mode/javascript/javascript", "codemirror/mode/xml/xml", "file-saver", - "qrcode" + "qrcode", + "codemirror" ] }, "configurations": { diff --git a/console/package-lock.json b/console/package-lock.json index f8ea65a828..acdadd6fde 100644 --- a/console/package-lock.json +++ b/console/package-lock.json @@ -8,26 +8,23 @@ "name": "console", "version": "0.0.0", "dependencies": { - "@angular/animations": "^15.2.6", - "@angular/cdk": "^15.2.6", - "@angular/common": "^15.2.6", - "@angular/compiler": "^15.2.6", - "@angular/core": "^15.2.6", - "@angular/forms": "^15.2.6", - "@angular/material": "^15.2.6", - "@angular/material-moment-adapter": "^15.2.6", - "@angular/platform-browser": "^15.2.6", - "@angular/platform-browser-dynamic": "^15.2.6", - "@angular/router": "^15.2.6", - "@angular/service-worker": "^15.2.6", + "@angular/animations": "^16.0.1", + "@angular/cdk": "^16.0.1", + "@angular/common": "^16.0.1", + "@angular/compiler": "^16.0.1", + "@angular/core": "^16.0.1", + "@angular/forms": "^16.0.1", + "@angular/material": "^16.0.1", + "@angular/material-moment-adapter": "^16.0.1", + "@angular/platform-browser": "^16.0.1", + "@angular/platform-browser-dynamic": "^16.0.1", + "@angular/router": "^16.0.1", + "@angular/service-worker": "^16.0.1", "@ctrl/ngx-codemirror": "^6.1.0", - "@grpc/grpc-js": "^1.8.12", + "@grpc/grpc-js": "^1.8.14", "@ngx-translate/core": "^14.0.0", - "@types/file-saver": "^2.0.2", - "@types/google-protobuf": "^3.15.3", - "@types/uuid": "^8.3.0", "angular-oauth2-oidc": "^15.0.1", - "angularx-qrcode": "^15.0.0", + "angularx-qrcode": "^16.0.0", "buffer": "^6.0.3", "codemirror": "^5.65.8", "cors": "^2.8.5", @@ -36,8 +33,8 @@ "google-proto-files": "^3.0.3", "google-protobuf": "^3.21.2", "grpc-web": "^1.4.1", - "i18n-iso-countries": "^7.5.0", - "libphonenumber-js": "^1.10.24", + "i18n-iso-countries": "^7.6.0", + "libphonenumber-js": "^1.10.30", "material-design-icons-iconfont": "^6.1.1", "moment": "^2.29.4", "ngx-color": "^8.0.3", @@ -48,31 +45,34 @@ "zone.js": "~0.13.0" }, "devDependencies": { - "@angular-devkit/build-angular": "^15.2.5", - "@angular-eslint/builder": "15.2.1", - "@angular-eslint/eslint-plugin": "15.2.1", - "@angular-eslint/eslint-plugin-template": "15.2.1", - "@angular-eslint/schematics": "15.2.1", - "@angular-eslint/template-parser": "15.2.1", - "@angular/cli": "^15.2.5", - "@angular/compiler-cli": "^15.2.6", - "@angular/language-service": "^15.2.6", - "@bufbuild/buf": "^1.14.0", + "@angular-devkit/build-angular": "^16.0.1", + "@angular-eslint/builder": "16.0.1", + "@angular-eslint/eslint-plugin": "16.0.1", + "@angular-eslint/eslint-plugin-template": "16.0.1", + "@angular-eslint/schematics": "16.0.1", + "@angular-eslint/template-parser": "16.0.1", + "@angular/cli": "^16.0.1", + "@angular/compiler-cli": "^16.0.1", + "@angular/language-service": "^16.0.1", + "@bufbuild/buf": "^1.18.0-1", + "@types/file-saver": "^2.0.2", + "@types/google-protobuf": "^3.15.3", "@types/jasmine": "~4.3.0", "@types/jasminewd2": "~2.0.10", "@types/jsonwebtoken": "^9.0.1", "@types/node": "^18.15.11", "@types/qrcode": "^1.5.0", - "@typescript-eslint/eslint-plugin": "5.48.2", - "@typescript-eslint/parser": "5.48.2", + "@types/uuid": "^9.0.1", + "@typescript-eslint/eslint-plugin": "^5.59.2", + "@typescript-eslint/parser": "^5.59.5", "codelyzer": "^6.0.2", - "eslint": "^8.33.0", + "eslint": "^8.39.0", "jasmine-core": "~4.6.0", "jasmine-spec-reporter": "~7.0.0", - "karma": "~6.4.1", - "karma-chrome-launcher": "~3.1.0", - "karma-coverage-istanbul-reporter": "~3.0.2", - "karma-jasmine": "~5.1.0", + "karma": "^6.4.2", + "karma-chrome-launcher": "^3.2.0", + "karma-coverage-istanbul-reporter": "^3.0.3", + "karma-jasmine": "^5.1.0", "karma-jasmine-html-reporter": "^2.0.0", "prettier": "^2.8.7", "prettier-plugin-organize-imports": "^3.2.2", @@ -81,12 +81,12 @@ } }, "node_modules/@ampproject/remapping": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", - "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", "dev": true, "dependencies": { - "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/gen-mapping": "^0.3.0", "@jridgewell/trace-mapping": "^0.3.9" }, "engines": { @@ -94,71 +94,54 @@ } }, "node_modules/@angular-devkit/architect": { - "version": "0.1502.5", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1502.5.tgz", - "integrity": "sha512-6KVrXQ/X7W88WSJvYe69ed/2QzQNlObKpj3BWzmcKnA+IvJB37/mvw8VaGFP9y+pDa/b1D1yCDtAJLeP5QY3xg==", + "version": "0.1600.1", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1600.1.tgz", + "integrity": "sha512-7N3Dugrp3Fyyn3Q6RsxFNJJ2m1QuqcF3GHJcX7siINL37Hp6xI/q5gKffcd9rf20H1DYZE0VIbR1Sk31G6hMWg==", "dev": true, "dependencies": { - "@angular-devkit/core": "15.2.5", - "rxjs": "6.6.7" + "@angular-devkit/core": "16.0.1", + "rxjs": "7.8.1" }, "engines": { - "node": "^14.20.0 || ^16.13.0 || >=18.10.0", + "node": "^16.14.0 || >=18.10.0", "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", "yarn": ">= 1.13.0" } }, - "node_modules/@angular-devkit/architect/node_modules/rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "dev": true, - "dependencies": { - "tslib": "^1.9.0" - }, - "engines": { - "npm": ">=2.0.0" - } - }, - "node_modules/@angular-devkit/architect/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, "node_modules/@angular-devkit/build-angular": { - "version": "15.2.5", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-15.2.5.tgz", - "integrity": "sha512-D2LxjBtUlgJnPxybOIN0XsENEGkVkqCGBBii5oK84HvgBHXO/EyP1WXpOdb2lOYSUZyjhOOs0q42LCobJoaxUw==", + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-16.0.1.tgz", + "integrity": "sha512-VFhUViBfONOf6Ji4Lfkxlk+GN5l8Owm4Z0McqUIegrXsq3aSSStBBFdaDESpzhS6GIGqEBjjHMUQK8IlWT+EIQ==", "dev": true, "dependencies": { - "@ampproject/remapping": "2.2.0", - "@angular-devkit/architect": "0.1502.5", - "@angular-devkit/build-webpack": "0.1502.5", - "@angular-devkit/core": "15.2.5", - "@babel/core": "7.20.12", - "@babel/generator": "7.20.14", + "@ampproject/remapping": "2.2.1", + "@angular-devkit/architect": "0.1600.1", + "@angular-devkit/build-webpack": "0.1600.1", + "@angular-devkit/core": "16.0.1", + "@babel/core": "7.21.4", + "@babel/generator": "7.21.4", "@babel/helper-annotate-as-pure": "7.18.6", "@babel/helper-split-export-declaration": "7.18.6", "@babel/plugin-proposal-async-generator-functions": "7.20.7", "@babel/plugin-transform-async-to-generator": "7.20.7", - "@babel/plugin-transform-runtime": "7.19.6", - "@babel/preset-env": "7.20.2", - "@babel/runtime": "7.20.13", + "@babel/plugin-transform-runtime": "7.21.4", + "@babel/preset-env": "7.21.4", + "@babel/runtime": "7.21.0", "@babel/template": "7.20.7", "@discoveryjs/json-ext": "0.5.7", - "@ngtools/webpack": "15.2.5", + "@ngtools/webpack": "16.0.1", + "@vitejs/plugin-basic-ssl": "1.0.1", "ansi-colors": "4.1.3", - "autoprefixer": "10.4.13", + "autoprefixer": "10.4.14", "babel-loader": "9.1.2", "babel-plugin-istanbul": "6.1.1", "browserslist": "4.21.5", - "cacache": "17.0.4", + "cacache": "17.0.6", "chokidar": "3.5.3", "copy-webpack-plugin": "11.0.0", "critters": "0.0.16", "css-loader": "6.7.3", - "esbuild-wasm": "0.17.8", + "esbuild-wasm": "0.17.18", "glob": "8.1.0", "https-proxy-agent": "5.0.1", "inquirer": "8.2.4", @@ -168,49 +151,54 @@ "less-loader": "11.1.0", "license-webpack-plugin": "4.0.2", "loader-utils": "3.2.1", - "magic-string": "0.29.0", - "mini-css-extract-plugin": "2.7.2", - "open": "8.4.1", + "magic-string": "0.30.0", + "mini-css-extract-plugin": "2.7.5", + "mrmime": "1.0.1", + "open": "8.4.2", "ora": "5.4.1", "parse5-html-rewriting-stream": "7.0.0", + "picomatch": "2.3.1", "piscina": "3.2.0", - "postcss": "8.4.21", - "postcss-loader": "7.0.2", + "postcss": "8.4.23", + "postcss-loader": "7.2.4", "resolve-url-loader": "5.0.0", - "rxjs": "6.6.7", - "sass": "1.58.1", - "sass-loader": "13.2.0", - "semver": "7.3.8", + "rxjs": "7.8.1", + "sass": "1.62.1", + "sass-loader": "13.2.2", + "semver": "7.4.0", "source-map-loader": "4.0.1", "source-map-support": "0.5.21", - "terser": "5.16.3", + "terser": "5.17.1", "text-table": "0.2.0", "tree-kill": "1.2.2", "tslib": "2.5.0", - "webpack": "5.76.1", - "webpack-dev-middleware": "6.0.1", - "webpack-dev-server": "4.11.1", + "vite": "4.3.1", + "webpack": "5.80.0", + "webpack-dev-middleware": "6.0.2", + "webpack-dev-server": "4.13.2", "webpack-merge": "5.8.0", "webpack-subresource-integrity": "5.1.0" }, "engines": { - "node": "^14.20.0 || ^16.13.0 || >=18.10.0", + "node": "^16.14.0 || >=18.10.0", "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", "yarn": ">= 1.13.0" }, "optionalDependencies": { - "esbuild": "0.17.8" + "esbuild": "0.17.18" }, "peerDependencies": { - "@angular/compiler-cli": "^15.0.0", - "@angular/localize": "^15.0.0", - "@angular/platform-server": "^15.0.0", - "@angular/service-worker": "^15.0.0", + "@angular/compiler-cli": "^16.0.0", + "@angular/localize": "^16.0.0", + "@angular/platform-server": "^16.0.0", + "@angular/service-worker": "^16.0.0", + "jest": "^29.5.0", + "jest-environment-jsdom": "^29.5.0", "karma": "^6.3.0", - "ng-packagr": "^15.0.0", + "ng-packagr": "^16.0.0", "protractor": "^7.0.0", "tailwindcss": "^2.0.0 || ^3.0.0", - "typescript": ">=4.8.2 <5.0" + "typescript": ">=4.9.3 <5.1" }, "peerDependenciesMeta": { "@angular/localize": { @@ -222,6 +210,12 @@ "@angular/service-worker": { "optional": true }, + "jest": { + "optional": true + }, + "jest-environment-jsdom": { + "optional": true + }, "karma": { "optional": true }, @@ -236,35 +230,17 @@ } } }, - "node_modules/@angular-devkit/build-angular/node_modules/rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "dev": true, - "dependencies": { - "tslib": "^1.9.0" - }, - "engines": { - "npm": ">=2.0.0" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/rxjs/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, "node_modules/@angular-devkit/build-webpack": { - "version": "0.1502.5", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1502.5.tgz", - "integrity": "sha512-gPkAa4AvQ7BxU+jmVJqrAO18kw/6iks+VUQ+2BVPyHCdqhroANHYdGbZ/pFlZdPmZVzSpusjd6VIbLhbHr/Ohw==", + "version": "0.1600.1", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1600.1.tgz", + "integrity": "sha512-yCy5A1UwGzpst3QJ/CRo2Y8HWRqTPOfwAPAVl91Lbch7gBFViRvq6E7N1XfQunPu/eXvKxbuq2mFSDqtyZ1mWw==", "dev": true, "dependencies": { - "@angular-devkit/architect": "0.1502.5", - "rxjs": "6.6.7" + "@angular-devkit/architect": "0.1600.1", + "rxjs": "7.8.1" }, "engines": { - "node": "^14.20.0 || ^16.13.0 || >=18.10.0", + "node": "^16.14.0 || >=18.10.0", "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", "yarn": ">= 1.13.0" }, @@ -273,38 +249,20 @@ "webpack-dev-server": "^4.0.0" } }, - "node_modules/@angular-devkit/build-webpack/node_modules/rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "dev": true, - "dependencies": { - "tslib": "^1.9.0" - }, - "engines": { - "npm": ">=2.0.0" - } - }, - "node_modules/@angular-devkit/build-webpack/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, "node_modules/@angular-devkit/core": { - "version": "15.2.5", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-15.2.5.tgz", - "integrity": "sha512-ZfjEkAe2yYeekc3xjZ/U4pK9nb+w6BFwAEjou6mE8PWZH7iYskm0YCCXkmu+B+zViEcCLhAkJAxu9MwX4efd8g==", + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-16.0.1.tgz", + "integrity": "sha512-2uz98IqkKJlgnHbWQ7VeL4pb+snGAZXIama2KXi+k9GsRntdcw+udX8rL3G9SdUGUF+m6+147Y1oRBMHsO/v4w==", "dev": true, "dependencies": { "ajv": "8.12.0", "ajv-formats": "2.1.1", "jsonc-parser": "3.2.0", - "rxjs": "6.6.7", + "rxjs": "7.8.1", "source-map": "0.7.4" }, "engines": { - "node": "^14.20.0 || ^16.13.0 || >=18.10.0", + "node": "^16.14.0 || >=18.10.0", "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", "yarn": ">= 1.13.0" }, @@ -317,84 +275,52 @@ } } }, - "node_modules/@angular-devkit/core/node_modules/rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "dev": true, - "dependencies": { - "tslib": "^1.9.0" - }, - "engines": { - "npm": ">=2.0.0" - } - }, - "node_modules/@angular-devkit/core/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, "node_modules/@angular-devkit/schematics": { - "version": "15.2.5", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-15.2.5.tgz", - "integrity": "sha512-zm7chQRQtPXQzzSAvK/mbZ+RJ3eP7hlU53yyJ/i6kjWAh3Y5uiSHNYGmqhhAHFuzw4Jhb4OC2S9iycxrqmI8TA==", + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-16.0.1.tgz", + "integrity": "sha512-A9D0LTYmiqiBa90GKcSuWb7hUouGIbm/AHbJbjL85WLLRbQA2PwKl7P5Mpd6nS/ZC0kfG4VQY3VOaDvb3qpI9g==", "dev": true, "dependencies": { - "@angular-devkit/core": "15.2.5", + "@angular-devkit/core": "16.0.1", "jsonc-parser": "3.2.0", - "magic-string": "0.29.0", + "magic-string": "0.30.0", "ora": "5.4.1", - "rxjs": "6.6.7" + "rxjs": "7.8.1" }, "engines": { - "node": "^14.20.0 || ^16.13.0 || >=18.10.0", + "node": "^16.14.0 || >=18.10.0", "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", "yarn": ">= 1.13.0" } }, - "node_modules/@angular-devkit/schematics/node_modules/rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "node_modules/@angular-eslint/builder": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/@angular-eslint/builder/-/builder-16.0.1.tgz", + "integrity": "sha512-yjFltV+r3YjisVjASMPmWB/ASz39wdh0q5g0l6/4G+8yaxl6hEYs5o0ZOGeGdTFstCql8FGY+QKwKgsq9Ec4QQ==", "dev": true, "dependencies": { - "tslib": "^1.9.0" + "@nx/devkit": "16.0.2", + "nx": "16.0.2" }, - "engines": { - "npm": ">=2.0.0" - } - }, - "node_modules/@angular-devkit/schematics/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "node_modules/@angular-eslint/builder": { - "version": "15.2.1", - "resolved": "https://registry.npmjs.org/@angular-eslint/builder/-/builder-15.2.1.tgz", - "integrity": "sha512-7x2DANebLRl997Mj4DhZrnz5+vnSjavGGveJ0mBuU7CEsL0ZYLftdRqL0e0HtU3ksseS7xpchD6OM08nkNgySw==", - "dev": true, "peerDependencies": { "eslint": "^7.20.0 || ^8.0.0", "typescript": "*" } }, "node_modules/@angular-eslint/bundled-angular-compiler": { - "version": "15.2.1", - "resolved": "https://registry.npmjs.org/@angular-eslint/bundled-angular-compiler/-/bundled-angular-compiler-15.2.1.tgz", - "integrity": "sha512-LO7Am8eVCr7oh6a0VmKSL7K03CnQEQhFO7Wt/YtbfYOxVjrbwmYLwJn+wZPOT7A02t/BttOD/WXuDrOWtSMQ/Q==", + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/@angular-eslint/bundled-angular-compiler/-/bundled-angular-compiler-16.0.1.tgz", + "integrity": "sha512-amvTgKHtZoygivW3LAYZ9qjLWsXM7/7eaRvaHdmAEdjyFnYQZ7UbWMPSQNz1mlW/AzTFvk9lGGQORglNOSDnww==", "dev": true }, "node_modules/@angular-eslint/eslint-plugin": { - "version": "15.2.1", - "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin/-/eslint-plugin-15.2.1.tgz", - "integrity": "sha512-OM7b1kS4E4CkXjkaWN+lEzawh4VxY6l7FO1Cuk4s7iv3/YpZG3rJxIZBqnFLTixwrBuqw8y4FNBzF3eDgmFAUw==", + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin/-/eslint-plugin-16.0.1.tgz", + "integrity": "sha512-CM9keS9cH1QAfSVfsvhw/oGCZcP/D8gfekWwVNjN/uEMEAak0czn1KOG7JQkE36NXOGtwCpTspMi1aa9CVKo9g==", "dev": true, "dependencies": { - "@angular-eslint/utils": "15.2.1", - "@typescript-eslint/utils": "5.48.2" + "@angular-eslint/utils": "16.0.1", + "@typescript-eslint/utils": "5.59.2" }, "peerDependencies": { "eslint": "^7.20.0 || ^8.0.0", @@ -402,15 +328,15 @@ } }, "node_modules/@angular-eslint/eslint-plugin-template": { - "version": "15.2.1", - "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin-template/-/eslint-plugin-template-15.2.1.tgz", - "integrity": "sha512-IeiSLk6YxapFdH2z5o/O3R7VwtBd2T6fWmhLFPwDYMDknrwegnOjwswCdBplOccpUp0wqlCeGUx7LTsuzwaz7w==", + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin-template/-/eslint-plugin-template-16.0.1.tgz", + "integrity": "sha512-1hyfs+Iq7K2x3mDDE4985d8vDcMyknbE9HKHKUtRLfLKC9gnV3N5d4+UeySQ7Rrjvgzkc1g9qHADyuhwRWpDSA==", "dev": true, "dependencies": { - "@angular-eslint/bundled-angular-compiler": "15.2.1", - "@angular-eslint/utils": "15.2.1", - "@typescript-eslint/type-utils": "5.48.2", - "@typescript-eslint/utils": "5.48.2", + "@angular-eslint/bundled-angular-compiler": "16.0.1", + "@angular-eslint/utils": "16.0.1", + "@typescript-eslint/type-utils": "5.59.2", + "@typescript-eslint/utils": "5.59.2", "aria-query": "5.1.3", "axobject-query": "3.1.1" }, @@ -420,28 +346,30 @@ } }, "node_modules/@angular-eslint/schematics": { - "version": "15.2.1", - "resolved": "https://registry.npmjs.org/@angular-eslint/schematics/-/schematics-15.2.1.tgz", - "integrity": "sha512-0ZfBCejHWIcgy3J5kFs9sS/jqi8i5AptxggOwFySOlCLJ+CzNrktjD4jff1Zy8K/VLzY0Ci0BSZXvgWfP0k9Rg==", + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/@angular-eslint/schematics/-/schematics-16.0.1.tgz", + "integrity": "sha512-1oJJEWVbgPkNK1E8rAJfrgxzNWWzJKv3frTHeAm8gvZ7GftYhHjDcrcnxLWrYNxb9+q8Awi0hvGta/4HROmmnA==", "dev": true, "dependencies": { - "@angular-eslint/eslint-plugin": "15.2.1", - "@angular-eslint/eslint-plugin-template": "15.2.1", + "@angular-eslint/eslint-plugin": "16.0.1", + "@angular-eslint/eslint-plugin-template": "16.0.1", + "@nx/devkit": "16.0.2", "ignore": "5.2.4", + "nx": "16.0.2", "strip-json-comments": "3.1.1", "tmp": "0.2.1" }, "peerDependencies": { - "@angular/cli": ">= 15.0.0 < 16.0.0" + "@angular/cli": ">= 16.0.0 < 17.0.0" } }, "node_modules/@angular-eslint/template-parser": { - "version": "15.2.1", - "resolved": "https://registry.npmjs.org/@angular-eslint/template-parser/-/template-parser-15.2.1.tgz", - "integrity": "sha512-ViCi79gC2aKJecmYLkOT+QlT5WMRNXeYz0Dr9Pr8qXzIbY0oAWE7nOT5jkXwQ9oUk+ybtGCWHma5JVJWVJsIog==", + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/@angular-eslint/template-parser/-/template-parser-16.0.1.tgz", + "integrity": "sha512-x0+SwSeqa3TiVZan6fE5grHsCkjGqU+zAS2DB6wAw5pyvgNAIjrI4cZEQ8pkgHfXe5tuumTKztlkpisah5s/hg==", "dev": true, "dependencies": { - "@angular-eslint/bundled-angular-compiler": "15.2.1", + "@angular-eslint/bundled-angular-compiler": "16.0.1", "eslint-scope": "^7.0.0" }, "peerDependencies": { @@ -450,13 +378,13 @@ } }, "node_modules/@angular-eslint/utils": { - "version": "15.2.1", - "resolved": "https://registry.npmjs.org/@angular-eslint/utils/-/utils-15.2.1.tgz", - "integrity": "sha512-++FneAJHxJqcSu0igVN6uOkSoHxlzgLoMBswuovYJy3UKwm33/T6WFku8++753Ca/JucIoR1gdUfO7SoSspMDg==", + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/@angular-eslint/utils/-/utils-16.0.1.tgz", + "integrity": "sha512-2xnJuhIrMZEYK6UyBym6FaFXZgopIIbqfQ4sAtMWY6zYkCEsVUvx5qKIrsnXAwvpDQrv0WiMXteqi/5ICpVMZQ==", "dev": true, "dependencies": { - "@angular-eslint/bundled-angular-compiler": "15.2.1", - "@typescript-eslint/utils": "5.48.2" + "@angular-eslint/bundled-angular-compiler": "16.0.1", + "@typescript-eslint/utils": "5.59.2" }, "peerDependencies": { "eslint": "^7.20.0 || ^8.0.0", @@ -464,23 +392,23 @@ } }, "node_modules/@angular/animations": { - "version": "15.2.6", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-15.2.6.tgz", - "integrity": "sha512-2fEhhj7xTzWHD61B502eXwDclsurkOK7CU+iRdl8EAtEobLRt62sG/XHmJ71UaaniWyI/H0sUSEJuF8TIPcaoQ==", + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-16.0.1.tgz", + "integrity": "sha512-ziRq1hGJJuQqQUHqNpEMp9uy1pVutvL8oNvawblh32u4bnLsVQU5gMd6sTonn0x4sphEwMNnuEmp/q6QRIx+pA==", "dependencies": { "tslib": "^2.3.0" }, "engines": { - "node": "^14.20.0 || ^16.13.0 || >=18.10.0" + "node": "^16.14.0 || >=18.10.0" }, "peerDependencies": { - "@angular/core": "15.2.6" + "@angular/core": "16.0.1" } }, "node_modules/@angular/cdk": { - "version": "15.2.6", - "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-15.2.6.tgz", - "integrity": "sha512-c6XFKMFowllHxb4tUt9en3bXBDqXKG2k4O9XGggJ1TL668d3Uhlk9qULywFNVWmNQSamkERmhFKAN4hEO3TPAQ==", + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-16.0.1.tgz", + "integrity": "sha512-GupYss6x84RWEoy3JTYu4Igr2SxHuV6whVKMScQG2/Gm+winOsOn7YWm0IZQuFnjSWIF2Va5B0Tp0IjFHWxTvA==", "dependencies": { "tslib": "^2.3.0" }, @@ -488,72 +416,72 @@ "parse5": "^7.1.2" }, "peerDependencies": { - "@angular/common": "^15.0.0 || ^16.0.0", - "@angular/core": "^15.0.0 || ^16.0.0", + "@angular/common": "^16.0.0 || ^17.0.0", + "@angular/core": "^16.0.0 || ^17.0.0", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/cli": { - "version": "15.2.5", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-15.2.5.tgz", - "integrity": "sha512-TmkkeJkdfDkC6b2SNQcLlr1rsl2anc5rrrY3gawOVXYXBExMxAi2SNJsHZzUXfiitW52aZkAyajF1VFazs8PRw==", + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-16.0.1.tgz", + "integrity": "sha512-0vIAcq/S+3NXXN4/gBQFVGaxLUQ0zhRxxHQQuiT7GGII73UySuhwvaFB1BEhYG5HVJjRrP1F0ZYbvsvrmFzfXQ==", "dev": true, "dependencies": { - "@angular-devkit/architect": "0.1502.5", - "@angular-devkit/core": "15.2.5", - "@angular-devkit/schematics": "15.2.5", - "@schematics/angular": "15.2.5", + "@angular-devkit/architect": "0.1600.1", + "@angular-devkit/core": "16.0.1", + "@angular-devkit/schematics": "16.0.1", + "@schematics/angular": "16.0.1", "@yarnpkg/lockfile": "1.1.0", "ansi-colors": "4.1.3", - "ini": "3.0.1", + "ini": "4.0.0", "inquirer": "8.2.4", "jsonc-parser": "3.2.0", "npm-package-arg": "10.1.0", "npm-pick-manifest": "8.0.1", - "open": "8.4.1", + "open": "8.4.2", "ora": "5.4.1", - "pacote": "15.1.0", - "resolve": "1.22.1", - "semver": "7.3.8", + "pacote": "15.1.3", + "resolve": "1.22.2", + "semver": "7.4.0", "symbol-observable": "4.0.0", - "yargs": "17.6.2" + "yargs": "17.7.2" }, "bin": { "ng": "bin/ng.js" }, "engines": { - "node": "^14.20.0 || ^16.13.0 || >=18.10.0", + "node": "^16.14.0 || >=18.10.0", "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", "yarn": ">= 1.13.0" } }, "node_modules/@angular/common": { - "version": "15.2.6", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-15.2.6.tgz", - "integrity": "sha512-kPGJoSkFPXsIeHzcjlal8JC8/jYK9qAr+wv+HDX8O1J2FEzQjwoX4SYvpnvVk5WTqUkxMkRCTMu2YFAAmU1+qg==", + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-16.0.1.tgz", + "integrity": "sha512-ic9Ri4Mepf4c0BTff7o4Oyl/a1vACNXXUzuoTwIjWnIqrH89dtwg7ncTD9Rv0N1lon7r4gXokTbn9A/Yk/0jbw==", "dependencies": { "tslib": "^2.3.0" }, "engines": { - "node": "^14.20.0 || ^16.13.0 || >=18.10.0" + "node": "^16.14.0 || >=18.10.0" }, "peerDependencies": { - "@angular/core": "15.2.6", + "@angular/core": "16.0.1", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/compiler": { - "version": "15.2.6", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-15.2.6.tgz", - "integrity": "sha512-6oBAIY5KcC1UNsrnWGLcopZ9RD7c0HzpTCQY46N6HytHtUjBvzLbGWZu5MfahPtIjKz9FMVYBX9hugcbVpWnTA==", + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-16.0.1.tgz", + "integrity": "sha512-7zNo6H1qVQow3T4EUul76SaIDSMRSl0hmtyWUzPjtWkxMjrCPSduqjA4/NHaG0KX1BsUvUtQEoDJ5jv/7EHWTQ==", "dependencies": { "tslib": "^2.3.0" }, "engines": { - "node": "^14.20.0 || ^16.13.0 || >=18.10.0" + "node": "^16.14.0 || >=18.10.0" }, "peerDependencies": { - "@angular/core": "15.2.6" + "@angular/core": "16.0.1" }, "peerDependenciesMeta": { "@angular/core": { @@ -562,17 +490,15 @@ } }, "node_modules/@angular/compiler-cli": { - "version": "15.2.6", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-15.2.6.tgz", - "integrity": "sha512-GHwL4l+NkaUGGdypF+nMFWCmTqvGusTzIriIwpnp38wc8lpmVME2jVodB6sHAkrxFmaHXU/gOCDFK4AnOi6Gmw==", + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-16.0.1.tgz", + "integrity": "sha512-EW7Oxp8EuTz3vCNd4RAncZGB7dCUYviUkBA4PzuyPmL2copZPt12j9qx0pXXF3T6ydjoZ+99ZEgfkKOV6FeU3g==", "dev": true, "dependencies": { "@babel/core": "7.19.3", "@jridgewell/sourcemap-codec": "^1.4.14", "chokidar": "^3.0.0", "convert-source-map": "^1.5.1", - "dependency-graph": "^0.11.0", - "magic-string": "^0.27.0", "reflect-metadata": "^0.1.2", "semver": "^7.0.0", "tslib": "^2.3.0", @@ -581,14 +507,14 @@ "bin": { "ng-xi18n": "bundles/src/bin/ng_xi18n.js", "ngc": "bundles/src/bin/ngc.js", - "ngcc": "bundles/ngcc/main-ngcc.js" + "ngcc": "bundles/ngcc/index.js" }, "engines": { - "node": "^14.20.0 || ^16.13.0 || >=18.10.0" + "node": "^16.14.0 || >=18.10.0" }, "peerDependencies": { - "@angular/compiler": "15.2.6", - "typescript": ">=4.8.2 <5.0" + "@angular/compiler": "16.0.1", + "typescript": ">=4.9.3 <5.1" } }, "node_modules/@angular/compiler-cli/node_modules/@babel/core": { @@ -630,150 +556,138 @@ "semver": "bin/semver.js" } }, - "node_modules/@angular/compiler-cli/node_modules/magic-string": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz", - "integrity": "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==", - "dev": true, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.13" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/@angular/core": { - "version": "15.2.6", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-15.2.6.tgz", - "integrity": "sha512-eN46OfSOLQGN6AciUvyHOJ8xQxmiEakkxJeoG1jwcSRXCjwSYYnQ/6drnhUpq5p43XXBAIduKfJXNztEPvLAkA==", + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-16.0.1.tgz", + "integrity": "sha512-3s4XBbzWgyWcjI0WFlNDKRxsbm4J+OKIL4mJCM9r8gWwno9y0K/giziAm9YMIJ4VOBIvrcMbOh85o44FCk8cRA==", "dependencies": { "tslib": "^2.3.0" }, "engines": { - "node": "^14.20.0 || ^16.13.0 || >=18.10.0" + "node": "^16.14.0 || >=18.10.0" }, "peerDependencies": { "rxjs": "^6.5.3 || ^7.4.0", - "zone.js": "~0.11.4 || ~0.12.0 || ~0.13.0" + "zone.js": "~0.13.0" } }, "node_modules/@angular/forms": { - "version": "15.2.6", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-15.2.6.tgz", - "integrity": "sha512-SdZxsE9MUOVMz0FjOwtx1RN/SGpObnAyZBqXNrN0c4BmJg+faJzvKIBBN102CKpWZOGRoq2YYrgxow9StMhxTw==", + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-16.0.1.tgz", + "integrity": "sha512-VbH/YnEBau0q97zI7BjSk0pu/i2S0Y/zmhvA2wgI2CCvtbqT6hCNdE/3rW6ZFBcnuCe+dFhuchXe6dX28epsvg==", "dependencies": { "tslib": "^2.3.0" }, "engines": { - "node": "^14.20.0 || ^16.13.0 || >=18.10.0" + "node": "^16.14.0 || >=18.10.0" }, "peerDependencies": { - "@angular/common": "15.2.6", - "@angular/core": "15.2.6", - "@angular/platform-browser": "15.2.6", + "@angular/common": "16.0.1", + "@angular/core": "16.0.1", + "@angular/platform-browser": "16.0.1", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/language-service": { - "version": "15.2.6", - "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-15.2.6.tgz", - "integrity": "sha512-q6u4XhFReJ3GtA7dC5rJaEBQPjJUjOz9PlwHSOxZxugFP99ddDNBBFd0caa446G54kQdZFG7j7w7BiAp2/srmQ==", + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-16.0.1.tgz", + "integrity": "sha512-m5+B0vi92le8EIxrlOruijNSjYG2Nny8hrAwt4yhoMr9HIym9nGeMXgYKYurMnqigI7zq/ZwJfnpmZ7QwjYkgA==", "dev": true, "engines": { - "node": "^14.20.0 || ^16.13.0 || >=18.10.0" + "node": "^16.14.0 || >=18.10.0" } }, "node_modules/@angular/material": { - "version": "15.2.6", - "resolved": "https://registry.npmjs.org/@angular/material/-/material-15.2.6.tgz", - "integrity": "sha512-r5feEcgs+xufI+GaO01XCehpnJVNB8sMS4l8DRV72DzgEIXhqYoLSWnQy7gYOKRXCUT66r1BxDmPG5fGa7jNzg==", + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/@angular/material/-/material-16.0.1.tgz", + "integrity": "sha512-J7qI60CXgixSLtepxzKzSkid9pxgruUfQDfZeTXSzg7WFb7/OgFeggUx0p/BlbC2NIdTaIFBBh71GNve/c1O9Q==", "dependencies": { - "@material/animation": "15.0.0-canary.684e33d25.0", - "@material/auto-init": "15.0.0-canary.684e33d25.0", - "@material/banner": "15.0.0-canary.684e33d25.0", - "@material/base": "15.0.0-canary.684e33d25.0", - "@material/button": "15.0.0-canary.684e33d25.0", - "@material/card": "15.0.0-canary.684e33d25.0", - "@material/checkbox": "15.0.0-canary.684e33d25.0", - "@material/chips": "15.0.0-canary.684e33d25.0", - "@material/circular-progress": "15.0.0-canary.684e33d25.0", - "@material/data-table": "15.0.0-canary.684e33d25.0", - "@material/density": "15.0.0-canary.684e33d25.0", - "@material/dialog": "15.0.0-canary.684e33d25.0", - "@material/dom": "15.0.0-canary.684e33d25.0", - "@material/drawer": "15.0.0-canary.684e33d25.0", - "@material/elevation": "15.0.0-canary.684e33d25.0", - "@material/fab": "15.0.0-canary.684e33d25.0", - "@material/feature-targeting": "15.0.0-canary.684e33d25.0", - "@material/floating-label": "15.0.0-canary.684e33d25.0", - "@material/form-field": "15.0.0-canary.684e33d25.0", - "@material/icon-button": "15.0.0-canary.684e33d25.0", - "@material/image-list": "15.0.0-canary.684e33d25.0", - "@material/layout-grid": "15.0.0-canary.684e33d25.0", - "@material/line-ripple": "15.0.0-canary.684e33d25.0", - "@material/linear-progress": "15.0.0-canary.684e33d25.0", - "@material/list": "15.0.0-canary.684e33d25.0", - "@material/menu": "15.0.0-canary.684e33d25.0", - "@material/menu-surface": "15.0.0-canary.684e33d25.0", - "@material/notched-outline": "15.0.0-canary.684e33d25.0", - "@material/radio": "15.0.0-canary.684e33d25.0", - "@material/ripple": "15.0.0-canary.684e33d25.0", - "@material/rtl": "15.0.0-canary.684e33d25.0", - "@material/segmented-button": "15.0.0-canary.684e33d25.0", - "@material/select": "15.0.0-canary.684e33d25.0", - "@material/shape": "15.0.0-canary.684e33d25.0", - "@material/slider": "15.0.0-canary.684e33d25.0", - "@material/snackbar": "15.0.0-canary.684e33d25.0", - "@material/switch": "15.0.0-canary.684e33d25.0", - "@material/tab": "15.0.0-canary.684e33d25.0", - "@material/tab-bar": "15.0.0-canary.684e33d25.0", - "@material/tab-indicator": "15.0.0-canary.684e33d25.0", - "@material/tab-scroller": "15.0.0-canary.684e33d25.0", - "@material/textfield": "15.0.0-canary.684e33d25.0", - "@material/theme": "15.0.0-canary.684e33d25.0", - "@material/tooltip": "15.0.0-canary.684e33d25.0", - "@material/top-app-bar": "15.0.0-canary.684e33d25.0", - "@material/touch-target": "15.0.0-canary.684e33d25.0", - "@material/typography": "15.0.0-canary.684e33d25.0", + "@material/animation": "15.0.0-canary.3b5b55e31.0", + "@material/auto-init": "15.0.0-canary.3b5b55e31.0", + "@material/banner": "15.0.0-canary.3b5b55e31.0", + "@material/base": "15.0.0-canary.3b5b55e31.0", + "@material/button": "15.0.0-canary.3b5b55e31.0", + "@material/card": "15.0.0-canary.3b5b55e31.0", + "@material/checkbox": "15.0.0-canary.3b5b55e31.0", + "@material/chips": "15.0.0-canary.3b5b55e31.0", + "@material/circular-progress": "15.0.0-canary.3b5b55e31.0", + "@material/data-table": "15.0.0-canary.3b5b55e31.0", + "@material/density": "15.0.0-canary.3b5b55e31.0", + "@material/dialog": "15.0.0-canary.3b5b55e31.0", + "@material/dom": "15.0.0-canary.3b5b55e31.0", + "@material/drawer": "15.0.0-canary.3b5b55e31.0", + "@material/elevation": "15.0.0-canary.3b5b55e31.0", + "@material/fab": "15.0.0-canary.3b5b55e31.0", + "@material/feature-targeting": "15.0.0-canary.3b5b55e31.0", + "@material/floating-label": "15.0.0-canary.3b5b55e31.0", + "@material/form-field": "15.0.0-canary.3b5b55e31.0", + "@material/icon-button": "15.0.0-canary.3b5b55e31.0", + "@material/image-list": "15.0.0-canary.3b5b55e31.0", + "@material/layout-grid": "15.0.0-canary.3b5b55e31.0", + "@material/line-ripple": "15.0.0-canary.3b5b55e31.0", + "@material/linear-progress": "15.0.0-canary.3b5b55e31.0", + "@material/list": "15.0.0-canary.3b5b55e31.0", + "@material/menu": "15.0.0-canary.3b5b55e31.0", + "@material/menu-surface": "15.0.0-canary.3b5b55e31.0", + "@material/notched-outline": "15.0.0-canary.3b5b55e31.0", + "@material/radio": "15.0.0-canary.3b5b55e31.0", + "@material/ripple": "15.0.0-canary.3b5b55e31.0", + "@material/rtl": "15.0.0-canary.3b5b55e31.0", + "@material/segmented-button": "15.0.0-canary.3b5b55e31.0", + "@material/select": "15.0.0-canary.3b5b55e31.0", + "@material/shape": "15.0.0-canary.3b5b55e31.0", + "@material/slider": "15.0.0-canary.3b5b55e31.0", + "@material/snackbar": "15.0.0-canary.3b5b55e31.0", + "@material/switch": "15.0.0-canary.3b5b55e31.0", + "@material/tab": "15.0.0-canary.3b5b55e31.0", + "@material/tab-bar": "15.0.0-canary.3b5b55e31.0", + "@material/tab-indicator": "15.0.0-canary.3b5b55e31.0", + "@material/tab-scroller": "15.0.0-canary.3b5b55e31.0", + "@material/textfield": "15.0.0-canary.3b5b55e31.0", + "@material/theme": "15.0.0-canary.3b5b55e31.0", + "@material/tooltip": "15.0.0-canary.3b5b55e31.0", + "@material/top-app-bar": "15.0.0-canary.3b5b55e31.0", + "@material/touch-target": "15.0.0-canary.3b5b55e31.0", + "@material/typography": "15.0.0-canary.3b5b55e31.0", "tslib": "^2.3.0" }, "peerDependencies": { - "@angular/animations": "^15.0.0 || ^16.0.0", - "@angular/cdk": "15.2.6", - "@angular/common": "^15.0.0 || ^16.0.0", - "@angular/core": "^15.0.0 || ^16.0.0", - "@angular/forms": "^15.0.0 || ^16.0.0", - "@angular/platform-browser": "^15.0.0 || ^16.0.0", + "@angular/animations": "^16.0.0 || ^17.0.0", + "@angular/cdk": "16.0.1", + "@angular/common": "^16.0.0 || ^17.0.0", + "@angular/core": "^16.0.0 || ^17.0.0", + "@angular/forms": "^16.0.0 || ^17.0.0", + "@angular/platform-browser": "^16.0.0 || ^17.0.0", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/material-moment-adapter": { - "version": "15.2.6", - "resolved": "https://registry.npmjs.org/@angular/material-moment-adapter/-/material-moment-adapter-15.2.6.tgz", - "integrity": "sha512-jE9dOQ3dYmNcPBqzWIdh3OQTPJymiUZLTuayPB3LqJ8hCfZ51W6hQ3c8WpZX3GyTlsDGmaveLXxcYWOufFp3cg==", + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/@angular/material-moment-adapter/-/material-moment-adapter-16.0.1.tgz", + "integrity": "sha512-sPSu0PhwG8qeanxpfDKw9a5WSqb1Y+LBxOCdEj5OAennPYfqwPf687BrzuP/7Y9hNwO9NAj5fLA3FJRz3lrQCw==", "dependencies": { "tslib": "^2.3.0" }, "peerDependencies": { - "@angular/core": "^15.0.0 || ^16.0.0", - "@angular/material": "15.2.6", + "@angular/core": "^16.0.0 || ^17.0.0", + "@angular/material": "16.0.1", "moment": "^2.18.1" } }, "node_modules/@angular/platform-browser": { - "version": "15.2.6", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-15.2.6.tgz", - "integrity": "sha512-8afckDEWfYf+cyxs2SboZBJkiCwFgYE8IH24RUW1t3zLC+wfrTr7UEfrCoD4YJRVJdqnPoRWN5gjz98n3n4zsA==", + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-16.0.1.tgz", + "integrity": "sha512-7XLIOnTnGDJLE4Q0zBz6eI9q5V3NnsTAJqIICJHc4gk6jNgVz90gtejAQ4EFbo0d83XGzwFL22hxID5Dj1WRIA==", "dependencies": { "tslib": "^2.3.0" }, "engines": { - "node": "^14.20.0 || ^16.13.0 || >=18.10.0" + "node": "^16.14.0 || >=18.10.0" }, "peerDependencies": { - "@angular/animations": "15.2.6", - "@angular/common": "15.2.6", - "@angular/core": "15.2.6" + "@angular/animations": "16.0.1", + "@angular/common": "16.0.1", + "@angular/core": "16.0.1" }, "peerDependenciesMeta": { "@angular/animations": { @@ -782,43 +696,43 @@ } }, "node_modules/@angular/platform-browser-dynamic": { - "version": "15.2.6", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-15.2.6.tgz", - "integrity": "sha512-ZSyiigpxBWIM5f8t/a28Y3BCzHn1FtI2KsJysE7di5UUflOzwbxbfycVlpiZp0girbDYRyF18vvefvitNh17Gw==", + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-16.0.1.tgz", + "integrity": "sha512-qrGlRPqJM42WZcHCbzwTA8SiK90xrhM/VrOL/8/1okuHn82gSWbbynpqycdZnsI9XMbW+HNhpKR2n8HKV38Jug==", "dependencies": { "tslib": "^2.3.0" }, "engines": { - "node": "^14.20.0 || ^16.13.0 || >=18.10.0" + "node": "^16.14.0 || >=18.10.0" }, "peerDependencies": { - "@angular/common": "15.2.6", - "@angular/compiler": "15.2.6", - "@angular/core": "15.2.6", - "@angular/platform-browser": "15.2.6" + "@angular/common": "16.0.1", + "@angular/compiler": "16.0.1", + "@angular/core": "16.0.1", + "@angular/platform-browser": "16.0.1" } }, "node_modules/@angular/router": { - "version": "15.2.6", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-15.2.6.tgz", - "integrity": "sha512-yB9uc9Xi9N0dErsugleywBA1KYG+GQ9WWSlri34oe2VsCqZazImn71n4wKPtrm2Xiy/mI23wJcr+jiCAtzp49Q==", + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-16.0.1.tgz", + "integrity": "sha512-4GH0SxPbuY08B/M0f3NEHf9yIFH+D3wlzWJHI75chfdqQ8gGAMG6B6PSmo3haicDxHcSnZTYNJXDLOQvaBAHcA==", "dependencies": { "tslib": "^2.3.0" }, "engines": { - "node": "^14.20.0 || ^16.13.0 || >=18.10.0" + "node": "^16.14.0 || >=18.10.0" }, "peerDependencies": { - "@angular/common": "15.2.6", - "@angular/core": "15.2.6", - "@angular/platform-browser": "15.2.6", + "@angular/common": "16.0.1", + "@angular/core": "16.0.1", + "@angular/platform-browser": "16.0.1", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/service-worker": { - "version": "15.2.6", - "resolved": "https://registry.npmjs.org/@angular/service-worker/-/service-worker-15.2.6.tgz", - "integrity": "sha512-7CoZqfWtDPYbyGRVPzgk26Fx49sd+hjboMGGDis3R47rJLfk+Hdkba2r43F2k1GGqD/goSpxHmnuocKe7oQi8g==", + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/@angular/service-worker/-/service-worker-16.0.1.tgz", + "integrity": "sha512-SkpE09QPwO80RJjlmyAka9/6c1DWUBEehH/LIeT/FfQ/6fOVUHgh5vgK8ha43rlDlkLp+OdVuhxokwfzQyjtTA==", "dependencies": { "tslib": "^2.3.0" }, @@ -826,11 +740,11 @@ "ngsw-config": "ngsw-config.js" }, "engines": { - "node": "^14.20.0 || ^16.13.0 || >=18.10.0" + "node": "^16.14.0 || >=18.10.0" }, "peerDependencies": { - "@angular/common": "15.2.6", - "@angular/core": "15.2.6" + "@angular/common": "16.0.1", + "@angular/core": "16.0.1" } }, "node_modules/@assemblyscript/loader": { @@ -852,30 +766,30 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.4.tgz", - "integrity": "sha512-/DYyDpeCfaVinT40FPGdkkb+lYSKvsVuMjDAG7jPOWWiM1ibOaB9CXJAlc4d1QpP/U2q2P9jbrSlClKSErd55g==", + "version": "7.21.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.7.tgz", + "integrity": "sha512-KYMqFYTaenzMK4yUtf4EW9wc4N9ef80FsbMtkwool5zpwl4YrT1SdWYSTRcT94KO4hannogdS+LxY7L+arP3gA==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.20.12", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.12.tgz", - "integrity": "sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.4.tgz", + "integrity": "sha512-qt/YV149Jman/6AfmlxJ04LMIu8bMoyl3RB91yTFrxQmgbrSvQMy7cI8Q62FHx1t8wJ8B5fu0UDoLwHAhUo1QA==", "dev": true, "dependencies": { - "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.7", - "@babel/helper-compilation-targets": "^7.20.7", - "@babel/helper-module-transforms": "^7.20.11", - "@babel/helpers": "^7.20.7", - "@babel/parser": "^7.20.7", + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.21.4", + "@babel/generator": "^7.21.4", + "@babel/helper-compilation-targets": "^7.21.4", + "@babel/helper-module-transforms": "^7.21.2", + "@babel/helpers": "^7.21.0", + "@babel/parser": "^7.21.4", "@babel/template": "^7.20.7", - "@babel/traverse": "^7.20.12", - "@babel/types": "^7.20.7", + "@babel/traverse": "^7.21.4", + "@babel/types": "^7.21.4", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -900,33 +814,20 @@ } }, "node_modules/@babel/generator": { - "version": "7.20.14", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.14.tgz", - "integrity": "sha512-AEmuXHdcD3A52HHXxaTmYlb8q/xMEhoRP67B3T4Oq7lbmSoqroMZzjnGj3+i1io3pdnF8iBYVu4Ilj+c4hBxYg==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.4.tgz", + "integrity": "sha512-NieM3pVIYW2SwGzKoqfPrQsf4xGs9M9AIG3ThppsSRmO+m7eQhmI6amajKMUeIO37wFfsvnvcxQFx6x6iqxDnA==", "dev": true, "dependencies": { - "@babel/types": "^7.20.7", + "@babel/types": "^7.21.4", "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", - "dev": true, - "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@babel/helper-annotate-as-pure": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", @@ -940,25 +841,24 @@ } }, "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz", - "integrity": "sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.21.5.tgz", + "integrity": "sha512-uNrjKztPLkUk7bpCNC0jEKDJzzkvel/W+HguzbN8krA+LPfC1CEobJEvAvGka2A/M+ViOqXdcRL0GqPUJSjx9g==", "dev": true, "dependencies": { - "@babel/helper-explode-assignable-expression": "^7.18.6", - "@babel/types": "^7.18.9" + "@babel/types": "^7.21.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.21.4.tgz", - "integrity": "sha512-Fa0tTuOXZ1iL8IeDFUWCzjZcn+sJGd9RZdH9esYVjEejGmzf+FFYQpMi/kZUk2kPy/q1H3/GPw7np8qar/stfg==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.21.5.tgz", + "integrity": "sha512-1RkbFGUKex4lvsB9yhIfWltJM5cZKUftB2eNajaDv3dCMEp49iBG0K14uH8NnX9IPux2+mK7JGEOB0jn48/J6w==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.21.4", + "@babel/compat-data": "^7.21.5", "@babel/helper-validator-option": "^7.21.0", "browserslist": "^4.21.3", "lru-cache": "^5.1.1", @@ -981,19 +881,20 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.21.4.tgz", - "integrity": "sha512-46QrX2CQlaFRF4TkwfTt6nJD7IHq8539cCL7SDpqWSDeJKY1xylKKY5F/33mJhLZ3mFvKv2gGrVS6NkyF6qs+Q==", + "version": "7.21.8", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.21.8.tgz", + "integrity": "sha512-+THiN8MqiH2AczyuZrnrKL6cAxFRRQDKW9h1YkBvbgKmAm6mwiacig1qT73DHIWMGo40GRnsEfN3LA+E6NtmSw==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-environment-visitor": "^7.21.5", "@babel/helper-function-name": "^7.21.0", - "@babel/helper-member-expression-to-functions": "^7.21.0", + "@babel/helper-member-expression-to-functions": "^7.21.5", "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-replace-supers": "^7.20.7", + "@babel/helper-replace-supers": "^7.21.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", - "@babel/helper-split-export-declaration": "^7.18.6" + "@babel/helper-split-export-declaration": "^7.18.6", + "semver": "^6.3.0" }, "engines": { "node": ">=6.9.0" @@ -1002,14 +903,24 @@ "@babel/core": "^7.0.0" } }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.21.4.tgz", - "integrity": "sha512-M00OuhU+0GyZ5iBBN9czjugzWrEq2vDpf/zCYHxxf93ul/Q5rv+a5h+/+0WnI1AebHNVtl5bFV0qsJoH23DbfA==", + "version": "7.21.8", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.21.8.tgz", + "integrity": "sha512-zGuSdedkFtsFHGbexAvNuipg1hbtitDLo2XE8/uf6Y9sOQV1xsYX/2pNbtedp/X0eU1pIt+kGvaqHCowkRbS5g==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.18.6", - "regexpu-core": "^5.3.1" + "regexpu-core": "^5.3.1", + "semver": "^6.3.0" }, "engines": { "node": ">=6.9.0" @@ -1018,6 +929,15 @@ "@babel/core": "^7.0.0" } }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/@babel/helper-define-polyfill-provider": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz", @@ -1045,26 +965,14 @@ } }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", - "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.21.5.tgz", + "integrity": "sha512-IYl4gZ3ETsWocUWgsFZLM5i1BYx9SoemminVEXadgLBa9TdeorzgLKm8wWLA6J1N/kT3Kch8XIk1laNzYoHKvQ==", "dev": true, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-explode-assignable-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz", - "integrity": "sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-function-name": { "version": "7.21.0", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz", @@ -1091,12 +999,12 @@ } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.21.0.tgz", - "integrity": "sha512-Muu8cdZwNN6mRRNG6lAYErJ5X3bRevgYR2O8wN0yn7jJSnGDu6eG59RfT29JHxGUovyfrh6Pj0XzmR7drNVL3Q==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.21.5.tgz", + "integrity": "sha512-nIcGfgwpH2u4n9GG1HpStW5Ogx7x7ekiFHbjjFRKXbn5zUvqO9ZgotCO4x1aNbKn/x/xOUaXEhyNHCwtFCpxWg==", "dev": true, "dependencies": { - "@babel/types": "^7.21.0" + "@babel/types": "^7.21.5" }, "engines": { "node": ">=6.9.0" @@ -1115,19 +1023,19 @@ } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.21.2", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.2.tgz", - "integrity": "sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.5.tgz", + "integrity": "sha512-bI2Z9zBGY2q5yMHoBvJ2a9iX3ZOAzJPm7Q8Yz6YeoUjU/Cvhmi2G4QyTNyPBqqXSgTjUxRg3L0xV45HvkNWWBw==", "dev": true, "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.20.2", + "@babel/helper-environment-visitor": "^7.21.5", + "@babel/helper-module-imports": "^7.21.4", + "@babel/helper-simple-access": "^7.21.5", "@babel/helper-split-export-declaration": "^7.18.6", "@babel/helper-validator-identifier": "^7.19.1", "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.2", - "@babel/types": "^7.21.2" + "@babel/traverse": "^7.21.5", + "@babel/types": "^7.21.5" }, "engines": { "node": ">=6.9.0" @@ -1146,9 +1054,9 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", - "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.21.5.tgz", + "integrity": "sha512-0WDaIlXKOX/3KfBK/dwP1oQGiPh6rjMkT7HIRv7i5RR2VUMwrx5ZL0dwBkKx7+SW1zwNdgjHd34IMk5ZjTeHVg==", "dev": true, "engines": { "node": ">=6.9.0" @@ -1173,29 +1081,29 @@ } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.20.7.tgz", - "integrity": "sha512-vujDMtB6LVfNW13jhlCrp48QNslK6JXi7lQG736HVbHz/mbf4Dc7tIRh1Xf5C0rF7BP8iiSxGMCmY6Ci1ven3A==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.21.5.tgz", + "integrity": "sha512-/y7vBgsr9Idu4M6MprbOVUfH3vs7tsIfnVWv/Ml2xgwvyH6LTngdfbf5AdsKwkJy4zgy1X/kuNrEKvhhK28Yrg==", "dev": true, "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-member-expression-to-functions": "^7.20.7", + "@babel/helper-environment-visitor": "^7.21.5", + "@babel/helper-member-expression-to-functions": "^7.21.5", "@babel/helper-optimise-call-expression": "^7.18.6", "@babel/template": "^7.20.7", - "@babel/traverse": "^7.20.7", - "@babel/types": "^7.20.7" + "@babel/traverse": "^7.21.5", + "@babel/types": "^7.21.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-simple-access": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", - "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.21.5.tgz", + "integrity": "sha512-ENPDAMC1wAjR0uaCUwliBdiSl1KBJAVnMTzXqi64c2MG8MPR6ii4qf7bSXDqSFbr4W6W028/rf5ivoHop5/mkg==", "dev": true, "dependencies": { - "@babel/types": "^7.20.2" + "@babel/types": "^7.21.5" }, "engines": { "node": ">=6.9.0" @@ -1226,9 +1134,9 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", - "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.21.5.tgz", + "integrity": "sha512-5pTUx3hAJaZIdW99sJ6ZUUgWq/Y+Hja7TowEnLNMm1VivRgZQL3vpBY3qUACVsvw+yQU6+YgfBVmcbLaZtrA1w==", "dev": true, "engines": { "node": ">=6.9.0" @@ -1268,14 +1176,14 @@ } }, "node_modules/@babel/helpers": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.21.0.tgz", - "integrity": "sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.21.5.tgz", + "integrity": "sha512-BSY+JSlHxOmGsPTydUkPf1MdMQ3M81x5xGCOVgWM3G8XH77sJ292Y2oqcp0CbbgxhqBuI46iUz1tT7hqP7EfgA==", "dev": true, "dependencies": { "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.0", - "@babel/types": "^7.21.0" + "@babel/traverse": "^7.21.5", + "@babel/types": "^7.21.5" }, "engines": { "node": ">=6.9.0" @@ -1296,9 +1204,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.4.tgz", - "integrity": "sha512-alVJj7k7zIxqBZ7BTRhz0IqJFxW1VJbm6N8JbcYhQ186df9ZBPbZBmWSqAMXwHGsCJdYks7z/voa3ibiS5bCIw==", + "version": "7.21.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.8.tgz", + "integrity": "sha512-6zavDGdzG3gUqAdWvlLFfk+36RilI+Pwyuuh7HItyeScCWP3k6i8vKclAQ0bM/0y/Kz/xiwvxhMv9MgTJP5gmA==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -1781,12 +1689,12 @@ } }, "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.20.7.tgz", - "integrity": "sha512-3poA5E7dzDomxj9WXWwuD6A5F3kc7VXwIJO+E+J8qtDtS+pXPAhrgEyh+9GBwBgPq1Z+bB+/JD60lp5jsN7JPQ==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.21.5.tgz", + "integrity": "sha512-wb1mhwGOCaXHDTcsRYMKF9e5bbMgqwxtqa2Y1ifH96dXJPwbuLX9qHy3clhrxVqgMz7nyNXs8VkxdH8UBcjKqA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-plugin-utils": "^7.21.5" }, "engines": { "node": ">=6.9.0" @@ -1866,12 +1774,12 @@ } }, "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.20.7.tgz", - "integrity": "sha512-Lz7MvBK6DTjElHAmfu6bfANzKcxpyNPeYBGEafyA6E5HtRpjpZwU+u7Qrgz/2OR0z+5TvKYbPdphfSaAcZBrYQ==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.21.5.tgz", + "integrity": "sha512-TR653Ki3pAwxBxUe8srfF3e4Pe3FTA46uaNHYyQwIoM4oWKSoOZiDNyHJ0oIoDIUPSRQbQG7jzgVBX3FPVne1Q==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-plugin-utils": "^7.21.5", "@babel/template": "^7.20.7" }, "engines": { @@ -1944,12 +1852,12 @@ } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.21.0.tgz", - "integrity": "sha512-LlUYlydgDkKpIY7mcBWvyPPmMcOphEyYA27Ef4xpbh1IiDNLr0kZsos2nf92vz3IccvJI25QUwp86Eo5s6HmBQ==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.21.5.tgz", + "integrity": "sha512-nYWpjKW/7j/I/mZkGVgHJXh4bA1sfdFnJoOXwJuj4m3Q2EraO/8ZyrkCau9P5tbHQk01RMSt6KYLCsW7730SXQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-plugin-utils": "^7.21.5" }, "engines": { "node": ">=6.9.0" @@ -2022,14 +1930,14 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.21.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.21.2.tgz", - "integrity": "sha512-Cln+Yy04Gxua7iPdj6nOV96smLGjpElir5YwzF0LBPKoPlLDNJePNlrGGaybAJkd0zKRnOVXOgizSqPYMNYkzA==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.21.5.tgz", + "integrity": "sha512-OVryBEgKUbtqMoB7eG2rs6UFexJi6Zj6FDXx+esBLPTCxCNxAY9o+8Di7IsUGJ+AVhp5ncK0fxWUBd0/1gPhrQ==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.21.2", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-simple-access": "^7.20.2" + "@babel/helper-module-transforms": "^7.21.5", + "@babel/helper-plugin-utils": "^7.21.5", + "@babel/helper-simple-access": "^7.21.5" }, "engines": { "node": ">=6.9.0" @@ -2150,12 +2058,12 @@ } }, "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.20.5.tgz", - "integrity": "sha512-kW/oO7HPBtntbsahzQ0qSE3tFvkFwnbozz3NWFhLGqH75vLEg+sCGngLlhVkePlCs3Jv0dBBHDzCHxNiFAQKCQ==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.21.5.tgz", + "integrity": "sha512-ZoYBKDb6LyMi5yCsByQ5jmXsHAQDDYeexT1Szvlmui+lADvfSecr5Dxd/PkrTC3pAD182Fcju1VQkB4oCp9M+w==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-plugin-utils": "^7.21.5", "regenerator-transform": "^0.15.1" }, "engines": { @@ -2181,13 +2089,13 @@ } }, "node_modules/@babel/plugin-transform-runtime": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.19.6.tgz", - "integrity": "sha512-PRH37lz4JU156lYFW1p8OxE5i7d6Sl/zV58ooyr+q1J1lnQPyg5tIiXlIwNVhJaY4W3TmOtdc8jqdXQcB1v5Yw==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.21.4.tgz", + "integrity": "sha512-1J4dhrw1h1PqnNNpzwxQ2UBymJUF8KuPjAAnlLwZcGhHAIqUigFW7cdK6GHoB64ubY4qXQNYknoUeks4Wz7CUA==", "dev": true, "dependencies": { - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-module-imports": "^7.21.4", + "@babel/helper-plugin-utils": "^7.20.2", "babel-plugin-polyfill-corejs2": "^0.3.3", "babel-plugin-polyfill-corejs3": "^0.6.0", "babel-plugin-polyfill-regenerator": "^0.4.1", @@ -2286,12 +2194,12 @@ } }, "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz", - "integrity": "sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.21.5.tgz", + "integrity": "sha512-LYm/gTOwZqsYohlvFUe/8Tujz75LqqVC2w+2qPHLR+WyWHGCZPN1KBpJCJn+4Bk4gOkQy/IXKIge6az5MqwlOg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.21.5" }, "engines": { "node": ">=6.9.0" @@ -2317,31 +2225,31 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.20.2.tgz", - "integrity": "sha512-1G0efQEWR1EHkKvKHqbG+IN/QdgwfByUpM5V5QroDzGV2t3S/WXNQd693cHiHTlCFMpr9B6FkPFXDA2lQcKoDg==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.21.4.tgz", + "integrity": "sha512-2W57zHs2yDLm6GD5ZpvNn71lZ0B/iypSdIeq25OurDKji6AdzV07qp4s3n1/x5BqtiGaTrPN3nerlSCaC5qNTw==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.20.1", - "@babel/helper-compilation-targets": "^7.20.0", + "@babel/compat-data": "^7.21.4", + "@babel/helper-compilation-targets": "^7.21.4", "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-validator-option": "^7.18.6", + "@babel/helper-validator-option": "^7.21.0", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9", - "@babel/plugin-proposal-async-generator-functions": "^7.20.1", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.20.7", + "@babel/plugin-proposal-async-generator-functions": "^7.20.7", "@babel/plugin-proposal-class-properties": "^7.18.6", - "@babel/plugin-proposal-class-static-block": "^7.18.6", + "@babel/plugin-proposal-class-static-block": "^7.21.0", "@babel/plugin-proposal-dynamic-import": "^7.18.6", "@babel/plugin-proposal-export-namespace-from": "^7.18.9", "@babel/plugin-proposal-json-strings": "^7.18.6", - "@babel/plugin-proposal-logical-assignment-operators": "^7.18.9", + "@babel/plugin-proposal-logical-assignment-operators": "^7.20.7", "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", "@babel/plugin-proposal-numeric-separator": "^7.18.6", - "@babel/plugin-proposal-object-rest-spread": "^7.20.2", + "@babel/plugin-proposal-object-rest-spread": "^7.20.7", "@babel/plugin-proposal-optional-catch-binding": "^7.18.6", - "@babel/plugin-proposal-optional-chaining": "^7.18.9", + "@babel/plugin-proposal-optional-chaining": "^7.21.0", "@babel/plugin-proposal-private-methods": "^7.18.6", - "@babel/plugin-proposal-private-property-in-object": "^7.18.6", + "@babel/plugin-proposal-private-property-in-object": "^7.21.0", "@babel/plugin-proposal-unicode-property-regex": "^7.18.6", "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-class-properties": "^7.12.13", @@ -2358,40 +2266,40 @@ "@babel/plugin-syntax-optional-chaining": "^7.8.3", "@babel/plugin-syntax-private-property-in-object": "^7.14.5", "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-transform-arrow-functions": "^7.18.6", - "@babel/plugin-transform-async-to-generator": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.20.7", + "@babel/plugin-transform-async-to-generator": "^7.20.7", "@babel/plugin-transform-block-scoped-functions": "^7.18.6", - "@babel/plugin-transform-block-scoping": "^7.20.2", - "@babel/plugin-transform-classes": "^7.20.2", - "@babel/plugin-transform-computed-properties": "^7.18.9", - "@babel/plugin-transform-destructuring": "^7.20.2", + "@babel/plugin-transform-block-scoping": "^7.21.0", + "@babel/plugin-transform-classes": "^7.21.0", + "@babel/plugin-transform-computed-properties": "^7.20.7", + "@babel/plugin-transform-destructuring": "^7.21.3", "@babel/plugin-transform-dotall-regex": "^7.18.6", "@babel/plugin-transform-duplicate-keys": "^7.18.9", "@babel/plugin-transform-exponentiation-operator": "^7.18.6", - "@babel/plugin-transform-for-of": "^7.18.8", + "@babel/plugin-transform-for-of": "^7.21.0", "@babel/plugin-transform-function-name": "^7.18.9", "@babel/plugin-transform-literals": "^7.18.9", "@babel/plugin-transform-member-expression-literals": "^7.18.6", - "@babel/plugin-transform-modules-amd": "^7.19.6", - "@babel/plugin-transform-modules-commonjs": "^7.19.6", - "@babel/plugin-transform-modules-systemjs": "^7.19.6", + "@babel/plugin-transform-modules-amd": "^7.20.11", + "@babel/plugin-transform-modules-commonjs": "^7.21.2", + "@babel/plugin-transform-modules-systemjs": "^7.20.11", "@babel/plugin-transform-modules-umd": "^7.18.6", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.19.1", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.20.5", "@babel/plugin-transform-new-target": "^7.18.6", "@babel/plugin-transform-object-super": "^7.18.6", - "@babel/plugin-transform-parameters": "^7.20.1", + "@babel/plugin-transform-parameters": "^7.21.3", "@babel/plugin-transform-property-literals": "^7.18.6", - "@babel/plugin-transform-regenerator": "^7.18.6", + "@babel/plugin-transform-regenerator": "^7.20.5", "@babel/plugin-transform-reserved-words": "^7.18.6", "@babel/plugin-transform-shorthand-properties": "^7.18.6", - "@babel/plugin-transform-spread": "^7.19.0", + "@babel/plugin-transform-spread": "^7.20.7", "@babel/plugin-transform-sticky-regex": "^7.18.6", "@babel/plugin-transform-template-literals": "^7.18.9", "@babel/plugin-transform-typeof-symbol": "^7.18.9", "@babel/plugin-transform-unicode-escapes": "^7.18.10", "@babel/plugin-transform-unicode-regex": "^7.18.6", "@babel/preset-modules": "^0.1.5", - "@babel/types": "^7.20.2", + "@babel/types": "^7.21.4", "babel-plugin-polyfill-corejs2": "^0.3.3", "babel-plugin-polyfill-corejs3": "^0.6.0", "babel-plugin-polyfill-regenerator": "^0.4.1", @@ -2437,9 +2345,9 @@ "dev": true }, "node_modules/@babel/runtime": { - "version": "7.20.13", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.13.tgz", - "integrity": "sha512-gt3PKXs0DBoL9xCvOIIZ2NEqAGZqHjAnmVbfQtB620V0uReIQutpel14KcneZuer7UioY8ALKZ7iocavvzTNFA==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.0.tgz", + "integrity": "sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==", "dev": true, "dependencies": { "regenerator-runtime": "^0.13.11" @@ -2463,19 +2371,19 @@ } }, "node_modules/@babel/traverse": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.4.tgz", - "integrity": "sha512-eyKrRHKdyZxqDm+fV1iqL9UAHMoIg0nDaGqfIOd8rKH17m5snv7Gn4qgjBoFfLz9APvjFU/ICT00NVCv1Epp8Q==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.5.tgz", + "integrity": "sha512-AhQoI3YjWi6u/y/ntv7k48mcrCXmus0t79J9qPNlk/lAsFlCiJ047RmbfMOawySTHtywXhbXgpx/8nXMYd+oFw==", "dev": true, "dependencies": { "@babel/code-frame": "^7.21.4", - "@babel/generator": "^7.21.4", - "@babel/helper-environment-visitor": "^7.18.9", + "@babel/generator": "^7.21.5", + "@babel/helper-environment-visitor": "^7.21.5", "@babel/helper-function-name": "^7.21.0", "@babel/helper-hoist-variables": "^7.18.6", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.21.4", - "@babel/types": "^7.21.4", + "@babel/parser": "^7.21.5", + "@babel/types": "^7.21.5", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -2484,12 +2392,12 @@ } }, "node_modules/@babel/traverse/node_modules/@babel/generator": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.4.tgz", - "integrity": "sha512-NieM3pVIYW2SwGzKoqfPrQsf4xGs9M9AIG3ThppsSRmO+m7eQhmI6amajKMUeIO37wFfsvnvcxQFx6x6iqxDnA==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.5.tgz", + "integrity": "sha512-SrKK/sRv8GesIW1bDagf9cCG38IOMYZusoe1dfg0D8aiUe3Amvoj1QtjTPAWcfrZFvIwlleLb0gxzQidL9w14w==", "dev": true, "dependencies": { - "@babel/types": "^7.21.4", + "@babel/types": "^7.21.5", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -2498,27 +2406,13 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/traverse/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", - "dev": true, - "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@babel/types": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.4.tgz", - "integrity": "sha512-rU2oY501qDxE8Pyo7i/Orqma4ziCOrby0/9mvbDUGEfvZjb279Nk9k19e2fiCxHbRRpY2ZyrgW1eq22mvmOIzA==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.5.tgz", + "integrity": "sha512-m4AfNvVF2mVC/F7fDEdH2El3HzUg9It/XsCxZiOTTA3m3qYfcSVSbTfM6Q9xG+hYDniZssYhlXKKUMD5m8tF4Q==", "dev": true, "dependencies": { - "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-string-parser": "^7.21.5", "@babel/helper-validator-identifier": "^7.19.1", "to-fast-properties": "^2.0.0" }, @@ -2527,9 +2421,9 @@ } }, "node_modules/@bufbuild/buf": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@bufbuild/buf/-/buf-1.15.0.tgz", - "integrity": "sha512-HX6AjKiI8TVFJKWdDGIUC/zZQG/8sf5FbmU5VdbK/U8tbfCwBADkJ6I+qP6HnDDtSU4obS164J0sibdGhAJKqg==", + "version": "1.18.0-1", + "resolved": "https://registry.npmjs.org/@bufbuild/buf/-/buf-1.18.0-1.tgz", + "integrity": "sha512-Js6BEbjsfM+aFo2bUxfTs0B4htDbjWCKZ8+FHV6YYqiVsin6NGGQsXblJxwt4+16HLfSnrf41RRnwUaBwHqBzQ==", "dev": true, "hasInstallScript": true, "bin": { @@ -2541,18 +2435,18 @@ "node": ">=12" }, "optionalDependencies": { - "@bufbuild/buf-darwin-arm64": "1.15.0", - "@bufbuild/buf-darwin-x64": "1.15.0", - "@bufbuild/buf-linux-aarch64": "1.15.0", - "@bufbuild/buf-linux-x64": "1.15.0", - "@bufbuild/buf-win32-arm64": "1.15.0", - "@bufbuild/buf-win32-x64": "1.15.0" + "@bufbuild/buf-darwin-arm64": "1.18.0-1", + "@bufbuild/buf-darwin-x64": "1.18.0-1", + "@bufbuild/buf-linux-aarch64": "1.18.0-1", + "@bufbuild/buf-linux-x64": "1.18.0-1", + "@bufbuild/buf-win32-arm64": "1.18.0-1", + "@bufbuild/buf-win32-x64": "1.18.0-1" } }, "node_modules/@bufbuild/buf-darwin-arm64": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@bufbuild/buf-darwin-arm64/-/buf-darwin-arm64-1.15.0.tgz", - "integrity": "sha512-sLN6uGc8sIBALa7Q4fB6rW9NM0MXK32pH6RRDUdl7aDrp/3A6TLKKBGiHcY81axUyxDTUNFb8dOwhHTI2H8FzQ==", + "version": "1.18.0-1", + "resolved": "https://registry.npmjs.org/@bufbuild/buf-darwin-arm64/-/buf-darwin-arm64-1.18.0-1.tgz", + "integrity": "sha512-4iFChDoXAiuMZQoXpJoCSvCkcT7p1fmsY2N/+wTdODQbXAwqR8vQz19FPR2Jv5ukhd44LUi43nFsyQ2dWmeZeA==", "cpu": [ "arm64" ], @@ -2566,9 +2460,9 @@ } }, "node_modules/@bufbuild/buf-darwin-x64": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@bufbuild/buf-darwin-x64/-/buf-darwin-x64-1.15.0.tgz", - "integrity": "sha512-iHml29I/hOl7ORyp9ohiV7fC1WqPbM5UjogwVpA8j06o5SgxRhp42nd80XRAXCM+65ecwiu5JVuspicGzQFOgg==", + "version": "1.18.0-1", + "resolved": "https://registry.npmjs.org/@bufbuild/buf-darwin-x64/-/buf-darwin-x64-1.18.0-1.tgz", + "integrity": "sha512-tuOnoCqFaUOj9dBuubEve5XGNkjL+zeCW7ETNgmArUlQobEkL2Fza5mi5Fqt90Ommfj1xpc4vaeNz1oSuU3dTw==", "cpu": [ "x64" ], @@ -2582,9 +2476,9 @@ } }, "node_modules/@bufbuild/buf-linux-aarch64": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@bufbuild/buf-linux-aarch64/-/buf-linux-aarch64-1.15.0.tgz", - "integrity": "sha512-YQHXqV1HhdpmIUrYg+gZNWCf43XHJJO5TlJT+pzXB/92PoN8gNP3KdxeRaM2sExcCs91G6zy1/Ms9N6DpeidUQ==", + "version": "1.18.0-1", + "resolved": "https://registry.npmjs.org/@bufbuild/buf-linux-aarch64/-/buf-linux-aarch64-1.18.0-1.tgz", + "integrity": "sha512-QdYp89hlLVPPZYlaeVhE0swk5Ygncij1avVmvLQw99+lvaFlDu9zRQ0Jo7n1VjpZWdDhUd/thYWxSqSMJYLajA==", "cpu": [ "arm64" ], @@ -2598,9 +2492,9 @@ } }, "node_modules/@bufbuild/buf-linux-x64": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@bufbuild/buf-linux-x64/-/buf-linux-x64-1.15.0.tgz", - "integrity": "sha512-DD2OcsfofawRPQKXLFMqV2GSzi4WyE7kKE1PvXBtJy7sombv5TM26vgdb+DQv4T4Z2i7vhKshnflNkfd3QXtXA==", + "version": "1.18.0-1", + "resolved": "https://registry.npmjs.org/@bufbuild/buf-linux-x64/-/buf-linux-x64-1.18.0-1.tgz", + "integrity": "sha512-9a6xv+OsYjhg5f1WHDtoXJVxG2j6awFi5cx9dkCPMODvFsll7skkwfkDngxKkibNU0aY6TxLoQXdf77eQwIWtQ==", "cpu": [ "x64" ], @@ -2614,9 +2508,9 @@ } }, "node_modules/@bufbuild/buf-win32-arm64": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@bufbuild/buf-win32-arm64/-/buf-win32-arm64-1.15.0.tgz", - "integrity": "sha512-wk65iDXWRicfrt/9Gb1voAn9eGP2giQfKMrKOoEyytnDHFolMSmQimKH6iQ1uS5Vn0gI/BVp582cF1m9YsbXEg==", + "version": "1.18.0-1", + "resolved": "https://registry.npmjs.org/@bufbuild/buf-win32-arm64/-/buf-win32-arm64-1.18.0-1.tgz", + "integrity": "sha512-UP6KevD0cdxa4IJcDy31KC9sIIgxCWBP/K9uW+gBDLg2cNQBtVqlN8o65PJhsl9HB+p0/Y4pDi4i/jU8dXGH8g==", "cpu": [ "arm64" ], @@ -2630,9 +2524,9 @@ } }, "node_modules/@bufbuild/buf-win32-x64": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@bufbuild/buf-win32-x64/-/buf-win32-x64-1.15.0.tgz", - "integrity": "sha512-KVoMj52ghYfLwGjQ+t19XZiQy8jGSGUYIe/yVZz08rsm5msXHGYOt++Bk3wr48rcv8gts8jo2/h1Ebkj+F6emw==", + "version": "1.18.0-1", + "resolved": "https://registry.npmjs.org/@bufbuild/buf-win32-x64/-/buf-win32-x64-1.18.0-1.tgz", + "integrity": "sha512-4OVbTwbQ1ZHGtITJw7hXYP2HinCWn3PN1ewCU+SCvynJTQ8vXQuVNlKZ2EmGl6aTUWdF3mSL/WPsRiG3fXhxfg==", "cpu": [ "x64" ], @@ -2654,6 +2548,30 @@ "node": ">=0.1.90" } }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "peer": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "peer": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, "node_modules/@ctrl/ngx-codemirror": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/@ctrl/ngx-codemirror/-/ngx-codemirror-6.1.0.tgz", @@ -2686,9 +2604,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.17.8", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.8.tgz", - "integrity": "sha512-0/rb91GYKhrtbeglJXOhAv9RuYimgI8h623TplY2X+vA4EXnk3Zj1fXZreJ0J3OJJu1bwmb0W7g+2cT/d8/l/w==", + "version": "0.17.18", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.18.tgz", + "integrity": "sha512-EmwL+vUBZJ7mhFCs5lA4ZimpUH3WMAoqvOIYhVQwdIgSpHC8ImHdsRyhHAVxpDYUSm0lWvd63z0XH1IlImS2Qw==", "cpu": [ "arm" ], @@ -2702,9 +2620,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.17.8", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.8.tgz", - "integrity": "sha512-oa/N5j6v1svZQs7EIRPqR8f+Bf8g6HBDjD/xHC02radE/NjKHK7oQmtmLxPs1iVwYyvE+Kolo6lbpfEQ9xnhxQ==", + "version": "0.17.18", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.18.tgz", + "integrity": "sha512-/iq0aK0eeHgSC3z55ucMAHO05OIqmQehiGay8eP5l/5l+iEr4EIbh4/MI8xD9qRFjqzgkc0JkX0LculNC9mXBw==", "cpu": [ "arm64" ], @@ -2718,9 +2636,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.17.8", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.8.tgz", - "integrity": "sha512-bTliMLqD7pTOoPg4zZkXqCDuzIUguEWLpeqkNfC41ODBHwoUgZ2w5JBeYimv4oP6TDVocoYmEhZrCLQTrH89bg==", + "version": "0.17.18", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.18.tgz", + "integrity": "sha512-x+0efYNBF3NPW2Xc5bFOSFW7tTXdAcpfEg2nXmxegm4mJuVeS+i109m/7HMiOQ6M12aVGGFlqJX3RhNdYM2lWg==", "cpu": [ "x64" ], @@ -2734,9 +2652,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.17.8", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.8.tgz", - "integrity": "sha512-ghAbV3ia2zybEefXRRm7+lx8J/rnupZT0gp9CaGy/3iolEXkJ6LYRq4IpQVI9zR97ID80KJVoUlo3LSeA/sMAg==", + "version": "0.17.18", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.18.tgz", + "integrity": "sha512-6tY+djEAdF48M1ONWnQb1C+6LiXrKjmqjzPNPWXhu/GzOHTHX2nh8Mo2ZAmBFg0kIodHhciEgUBtcYCAIjGbjQ==", "cpu": [ "arm64" ], @@ -2750,9 +2668,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.17.8", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.8.tgz", - "integrity": "sha512-n5WOpyvZ9TIdv2V1K3/iIkkJeKmUpKaCTdun9buhGRWfH//osmUjlv4Z5mmWdPWind/VGcVxTHtLfLCOohsOXw==", + "version": "0.17.18", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.18.tgz", + "integrity": "sha512-Qq84ykvLvya3dO49wVC9FFCNUfSrQJLbxhoQk/TE1r6MjHo3sFF2tlJCwMjhkBVq3/ahUisj7+EpRSz0/+8+9A==", "cpu": [ "x64" ], @@ -2766,9 +2684,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.17.8", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.8.tgz", - "integrity": "sha512-a/SATTaOhPIPFWvHZDoZYgxaZRVHn0/LX1fHLGfZ6C13JqFUZ3K6SMD6/HCtwOQ8HnsNaEeokdiDSFLuizqv5A==", + "version": "0.17.18", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.18.tgz", + "integrity": "sha512-fw/ZfxfAzuHfaQeMDhbzxp9mc+mHn1Y94VDHFHjGvt2Uxl10mT4CDavHm+/L9KG441t1QdABqkVYwakMUeyLRA==", "cpu": [ "arm64" ], @@ -2782,9 +2700,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.17.8", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.8.tgz", - "integrity": "sha512-xpFJb08dfXr5+rZc4E+ooZmayBW6R3q59daCpKZ/cDU96/kvDM+vkYzNeTJCGd8rtO6fHWMq5Rcv/1cY6p6/0Q==", + "version": "0.17.18", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.18.tgz", + "integrity": "sha512-FQFbRtTaEi8ZBi/A6kxOC0V0E9B/97vPdYjY9NdawyLd4Qk5VD5g2pbWN2VR1c0xhzcJm74HWpObPszWC+qTew==", "cpu": [ "x64" ], @@ -2798,9 +2716,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.17.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.8.tgz", - "integrity": "sha512-6Ij8gfuGszcEwZpi5jQIJCVIACLS8Tz2chnEBfYjlmMzVsfqBP1iGmHQPp7JSnZg5xxK9tjCc+pJ2WtAmPRFVA==", + "version": "0.17.18", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.18.tgz", + "integrity": "sha512-jW+UCM40LzHcouIaqv3e/oRs0JM76JfhHjCavPxMUti7VAPh8CaGSlS7cmyrdpzSk7A+8f0hiedHqr/LMnfijg==", "cpu": [ "arm" ], @@ -2814,9 +2732,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.17.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.8.tgz", - "integrity": "sha512-v3iwDQuDljLTxpsqQDl3fl/yihjPAyOguxuloON9kFHYwopeJEf1BkDXODzYyXEI19gisEsQlG1bM65YqKSIww==", + "version": "0.17.18", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.18.tgz", + "integrity": "sha512-R7pZvQZFOY2sxUG8P6A21eq6q+eBv7JPQYIybHVf1XkQYC+lT7nDBdC7wWKTrbvMXKRaGudp/dzZCwL/863mZQ==", "cpu": [ "arm64" ], @@ -2830,9 +2748,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.17.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.8.tgz", - "integrity": "sha512-8svILYKhE5XetuFk/B6raFYIyIqydQi+GngEXJgdPdI7OMKUbSd7uzR02wSY4kb53xBrClLkhH4Xs8P61Q2BaA==", + "version": "0.17.18", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.18.tgz", + "integrity": "sha512-ygIMc3I7wxgXIxk6j3V00VlABIjq260i967Cp9BNAk5pOOpIXmd1RFQJQX9Io7KRsthDrQYrtcx7QCof4o3ZoQ==", "cpu": [ "ia32" ], @@ -2846,9 +2764,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.17.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.8.tgz", - "integrity": "sha512-B6FyMeRJeV0NpyEOYlm5qtQfxbdlgmiGdD+QsipzKfFky0K5HW5Td6dyK3L3ypu1eY4kOmo7wW0o94SBqlqBSA==", + "version": "0.17.18", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.18.tgz", + "integrity": "sha512-bvPG+MyFs5ZlwYclCG1D744oHk1Pv7j8psF5TfYx7otCVmcJsEXgFEhQkbhNW8otDHL1a2KDINW20cfCgnzgMQ==", "cpu": [ "loong64" ], @@ -2862,9 +2780,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.17.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.8.tgz", - "integrity": "sha512-CCb67RKahNobjm/eeEqeD/oJfJlrWyw29fgiyB6vcgyq97YAf3gCOuP6qMShYSPXgnlZe/i4a8WFHBw6N8bYAA==", + "version": "0.17.18", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.18.tgz", + "integrity": "sha512-oVqckATOAGuiUOa6wr8TXaVPSa+6IwVJrGidmNZS1cZVx0HqkTMkqFGD2HIx9H1RvOwFeWYdaYbdY6B89KUMxA==", "cpu": [ "mips64el" ], @@ -2878,9 +2796,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.17.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.8.tgz", - "integrity": "sha512-bytLJOi55y55+mGSdgwZ5qBm0K9WOCh0rx+vavVPx+gqLLhxtSFU0XbeYy/dsAAD6xECGEv4IQeFILaSS2auXw==", + "version": "0.17.18", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.18.tgz", + "integrity": "sha512-3dLlQO+b/LnQNxgH4l9rqa2/IwRJVN9u/bK63FhOPB4xqiRqlQAU0qDU3JJuf0BmaH0yytTBdoSBHrb2jqc5qQ==", "cpu": [ "ppc64" ], @@ -2894,9 +2812,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.17.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.8.tgz", - "integrity": "sha512-2YpRyQJmKVBEHSBLa8kBAtbhucaclb6ex4wchfY0Tj3Kg39kpjeJ9vhRU7x4mUpq8ISLXRXH1L0dBYjAeqzZAw==", + "version": "0.17.18", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.18.tgz", + "integrity": "sha512-/x7leOyDPjZV3TcsdfrSI107zItVnsX1q2nho7hbbQoKnmoeUWjs+08rKKt4AUXju7+3aRZSsKrJtaRmsdL1xA==", "cpu": [ "riscv64" ], @@ -2910,9 +2828,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.17.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.8.tgz", - "integrity": "sha512-QgbNY/V3IFXvNf11SS6exkpVcX0LJcob+0RWCgV9OiDAmVElnxciHIisoSix9uzYzScPmS6dJFbZULdSAEkQVw==", + "version": "0.17.18", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.18.tgz", + "integrity": "sha512-cX0I8Q9xQkL/6F5zWdYmVf5JSQt+ZfZD2bJudZrWD+4mnUvoZ3TDDXtDX2mUaq6upMFv9FlfIh4Gfun0tbGzuw==", "cpu": [ "s390x" ], @@ -2926,9 +2844,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.17.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.8.tgz", - "integrity": "sha512-mM/9S0SbAFDBc4OPoyP6SEOo5324LpUxdpeIUUSrSTOfhHU9hEfqRngmKgqILqwx/0DVJBzeNW7HmLEWp9vcOA==", + "version": "0.17.18", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.18.tgz", + "integrity": "sha512-66RmRsPlYy4jFl0vG80GcNRdirx4nVWAzJmXkevgphP1qf4dsLQCpSKGM3DUQCojwU1hnepI63gNZdrr02wHUA==", "cpu": [ "x64" ], @@ -2942,9 +2860,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.17.8", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.8.tgz", - "integrity": "sha512-eKUYcWaWTaYr9zbj8GertdVtlt1DTS1gNBWov+iQfWuWyuu59YN6gSEJvFzC5ESJ4kMcKR0uqWThKUn5o8We6Q==", + "version": "0.17.18", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.18.tgz", + "integrity": "sha512-95IRY7mI2yrkLlTLb1gpDxdC5WLC5mZDi+kA9dmM5XAGxCME0F8i4bYH4jZreaJ6lIZ0B8hTrweqG1fUyW7jbg==", "cpu": [ "x64" ], @@ -2958,9 +2876,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.17.8", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.8.tgz", - "integrity": "sha512-Vc9J4dXOboDyMXKD0eCeW0SIeEzr8K9oTHJU+Ci1mZc5njPfhKAqkRt3B/fUNU7dP+mRyralPu8QUkiaQn7iIg==", + "version": "0.17.18", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.18.tgz", + "integrity": "sha512-WevVOgcng+8hSZ4Q3BKL3n1xTv5H6Nb53cBrtzzEjDbbnOmucEVcZeGCsCOi9bAOcDYEeBZbD2SJNBxlfP3qiA==", "cpu": [ "x64" ], @@ -2974,9 +2892,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.17.8", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.8.tgz", - "integrity": "sha512-0xvOTNuPXI7ft1LYUgiaXtpCEjp90RuBBYovdd2lqAFxje4sEucurg30M1WIm03+3jxByd3mfo+VUmPtRSVuOw==", + "version": "0.17.18", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.18.tgz", + "integrity": "sha512-Rzf4QfQagnwhQXVBS3BYUlxmEbcV7MY+BH5vfDZekU5eYpcffHSyjU8T0xucKVuOcdCsMo+Ur5wmgQJH2GfNrg==", "cpu": [ "x64" ], @@ -2990,9 +2908,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.17.8", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.8.tgz", - "integrity": "sha512-G0JQwUI5WdEFEnYNKzklxtBheCPkuDdu1YrtRrjuQv30WsYbkkoixKxLLv8qhJmNI+ATEWquZe/N0d0rpr55Mg==", + "version": "0.17.18", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.18.tgz", + "integrity": "sha512-Kb3Ko/KKaWhjeAm2YoT/cNZaHaD1Yk/pa3FTsmqo9uFh1D1Rfco7BBLIPdDOozrObj2sahslFuAQGvWbgWldAg==", "cpu": [ "arm64" ], @@ -3006,9 +2924,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.17.8", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.8.tgz", - "integrity": "sha512-Fqy63515xl20OHGFykjJsMnoIWS+38fqfg88ClvPXyDbLtgXal2DTlhb1TfTX34qWi3u4I7Cq563QcHpqgLx8w==", + "version": "0.17.18", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.18.tgz", + "integrity": "sha512-0/xUMIdkVHwkvxfbd5+lfG7mHOf2FRrxNbPiKWg9C4fFrB8H0guClmaM3BFiRUYrznVoyxTIyC/Ou2B7QQSwmw==", "cpu": [ "ia32" ], @@ -3022,9 +2940,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.17.8", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.8.tgz", - "integrity": "sha512-1iuezdyDNngPnz8rLRDO2C/ZZ/emJLb72OsZeqQ6gL6Avko/XCXZw+NuxBSNhBAP13Hie418V7VMt9et1FMvpg==", + "version": "0.17.18", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.18.tgz", + "integrity": "sha512-qU25Ma1I3NqTSHJUOKi9sAH1/Mzuvlke0ioMJRthLXKm7JiSKVwFghlGbDLOO2sARECGhja4xYfRAZNPAkooYg==", "cpu": [ "x64" ], @@ -3053,23 +2971,23 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.0.tgz", - "integrity": "sha512-vITaYzIcNmjn5tF5uxcZ/ft7/RXGrMUIS9HalWckEOF6ESiwXKoMzAQf2UW0aVd6rnOeExTJVd5hmWXucBKGXQ==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz", + "integrity": "sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==", "dev": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/eslintrc": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.2.tgz", - "integrity": "sha512-3W4f5tDUra+pA+FzgugqL2pRimUTDJWKr7BINqOpkZrC0uYI0NIc0/JFgBROCU07HR6GieA5m3/rsPIhDmCXTQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz", + "integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.5.1", + "espree": "^9.5.2", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -3152,9 +3070,9 @@ } }, "node_modules/@eslint/js": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.38.0.tgz", - "integrity": "sha512-IoD2MfUnOV58ghIHCiil01PcohxjbYR/qCxsoC+xNgUwh1EY8jOOrYmu3d3a71+tJJ23uscEV4X2HJWMsPJu4g==", + "version": "8.40.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.40.0.tgz", + "integrity": "sha512-ElyB54bJIhXQYVKjDSvCkPO1iU1tSAeVQJbllWJq1XQSmmA4dgFk8CbiBGpiOPxleE48vDogxCtmMYku4HSVLA==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -3167,9 +3085,9 @@ "dev": true }, "node_modules/@grpc/grpc-js": { - "version": "1.8.13", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.8.13.tgz", - "integrity": "sha512-iY3jsdfbc0ARoCLFvbvUB8optgyb0r1XLPb142u+QtgBcKJYkCIFt3Fd/881KqjLYWjsBJF57N3b8Eop9NDfUA==", + "version": "1.8.14", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.8.14.tgz", + "integrity": "sha512-w84maJ6CKl5aApCMzFll0hxtFNT6or9WwMslobKaqWUEf1K+zhlL43bSQhFreyYWIWR+Z0xnVFC1KtLm4ZpM/A==", "dependencies": { "@grpc/proto-loader": "^0.7.0", "@types/node": ">=12.12.47" @@ -3179,15 +3097,15 @@ } }, "node_modules/@grpc/proto-loader": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.6.tgz", - "integrity": "sha512-QyAXR8Hyh7uMDmveWxDSUcJr9NAWaZ2I6IXgAYvQmfflwouTM+rArE2eEaCtLlRqO81j7pRLCt81IefUei6Zbw==", + "version": "0.7.7", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.7.tgz", + "integrity": "sha512-1TIeXOi8TuSCQprPItwoMymZXxWT0CPxUhkrkeCUH+D8U7QDwQ6b7SUz2MaLuWM2llT+J/TVFLmQI5KtML3BhQ==", "dependencies": { "@types/long": "^4.0.1", "lodash.camelcase": "^4.3.0", "long": "^4.0.0", "protobufjs": "^7.0.0", - "yargs": "^16.2.0" + "yargs": "^17.7.2" }, "bin": { "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" @@ -3196,41 +3114,6 @@ "node": ">=6" } }, - "node_modules/@grpc/proto-loader/node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/@grpc/proto-loader/node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@grpc/proto-loader/node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "engines": { - "node": ">=10" - } - }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.8", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", @@ -3264,6 +3147,102 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", + "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -3290,13 +3269,14 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", - "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", "dev": true, "dependencies": { - "@jridgewell/set-array": "^1.0.0", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" }, "engines": { "node": ">=6.0.0" @@ -3330,20 +3310,6 @@ "@jridgewell/trace-mapping": "^0.3.9" } }, - "node_modules/@jridgewell/source-map/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", - "dev": true, - "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.15", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", @@ -3373,769 +3339,770 @@ "dev": true }, "node_modules/@material/animation": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/animation/-/animation-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-5osi1z4JQIXcklPALbH/zTfOm2pDzHt9Fxm7ZyURy250xIZj6QjULRzPTnzOhC2ropfix9ra2Cfggbf0dcRbEQ==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/animation/-/animation-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-4OlCKqydjF3JtdioZ5TlpAkSxQyJUjL7jIXzf/xIU6MRVOD9kTyqgUkUKNAq+m0I7rtA834NbF7MVam9lMsdkQ==", "dependencies": { "tslib": "^2.1.0" } }, "node_modules/@material/auto-init": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/auto-init/-/auto-init-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-OigQTmrVzkcGvxNjOaIe5oItTFPgrO9xLewvharDI6m6yvO1z7OBnkcW+sFN6ggLNYNxd0O1u9v64vMsmeDABQ==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/auto-init/-/auto-init-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-s/04P52RsebfLmm0ivlvbW3XcVobZGs2vZM+/HHTX312f9lR9m2gNo3oxWnJKfpLrvzY6zo4NvC9Xb6ZBqvnag==", "dependencies": { - "@material/base": "15.0.0-canary.684e33d25.0", + "@material/base": "15.0.0-canary.3b5b55e31.0", "tslib": "^2.1.0" } }, "node_modules/@material/banner": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/banner/-/banner-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-PqtGp3KWzdu58rWv/DIvSfe38m5YKOBbAAbBinSvgadBb/da+IE1t5F7YPNKE1T5lJsQBGVUYx6QBIeXm+aI/A==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/banner/-/banner-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-m9zvT8heoKc0sTTJLzx6oWGnEfDkEaQW3UounjmEDwVc/PtiqmZ5qIzdXIseI+sIcFw7poJiyvTHjNrbLbPeiw==", "dependencies": { - "@material/base": "15.0.0-canary.684e33d25.0", - "@material/button": "15.0.0-canary.684e33d25.0", - "@material/dom": "15.0.0-canary.684e33d25.0", - "@material/elevation": "15.0.0-canary.684e33d25.0", - "@material/feature-targeting": "15.0.0-canary.684e33d25.0", - "@material/ripple": "15.0.0-canary.684e33d25.0", - "@material/rtl": "15.0.0-canary.684e33d25.0", - "@material/shape": "15.0.0-canary.684e33d25.0", - "@material/theme": "15.0.0-canary.684e33d25.0", - "@material/tokens": "15.0.0-canary.684e33d25.0", - "@material/typography": "15.0.0-canary.684e33d25.0", + "@material/base": "15.0.0-canary.3b5b55e31.0", + "@material/button": "15.0.0-canary.3b5b55e31.0", + "@material/dom": "15.0.0-canary.3b5b55e31.0", + "@material/elevation": "15.0.0-canary.3b5b55e31.0", + "@material/feature-targeting": "15.0.0-canary.3b5b55e31.0", + "@material/ripple": "15.0.0-canary.3b5b55e31.0", + "@material/rtl": "15.0.0-canary.3b5b55e31.0", + "@material/shape": "15.0.0-canary.3b5b55e31.0", + "@material/theme": "15.0.0-canary.3b5b55e31.0", + "@material/tokens": "15.0.0-canary.3b5b55e31.0", + "@material/typography": "15.0.0-canary.3b5b55e31.0", "tslib": "^2.1.0" } }, "node_modules/@material/base": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/base/-/base-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-oOaqb/SfjWwTKsdJUZmeh/Qrs41nIJI0N+zELsxnvbGjSIN1ZMAKYZFPMahqvC68OJ6+5CvJM8PoTNs5l+B8IQ==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/base/-/base-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-8DmOJMxY0srjMHPDWdpayEYgVlmpR0zNorpJwJCp/IVESNBo3/BpeZCaulb4goP58/O10yWCqDYewGs4LXfNUA==", "dependencies": { "tslib": "^2.1.0" } }, "node_modules/@material/button": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/button/-/button-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-Nkekk4edeX+ObVOa7UlwavaHdmckPV5wU4SAJf3iA3R61cmz+KsgAgpzfcwv5WfNhIlc2nLu8QYEecpHdo9d/w==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/button/-/button-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-O9EIe5xpGHM8NCb2FySv7jP0hXWckk6crxii1c2Y/BD9jhfac971kS6iAsWE2veXPE9b5S19g/n64iaaI6KxHg==", "dependencies": { - "@material/density": "15.0.0-canary.684e33d25.0", - "@material/dom": "15.0.0-canary.684e33d25.0", - "@material/elevation": "15.0.0-canary.684e33d25.0", - "@material/feature-targeting": "15.0.0-canary.684e33d25.0", - "@material/focus-ring": "15.0.0-canary.684e33d25.0", - "@material/ripple": "15.0.0-canary.684e33d25.0", - "@material/rtl": "15.0.0-canary.684e33d25.0", - "@material/shape": "15.0.0-canary.684e33d25.0", - "@material/theme": "15.0.0-canary.684e33d25.0", - "@material/tokens": "15.0.0-canary.684e33d25.0", - "@material/touch-target": "15.0.0-canary.684e33d25.0", - "@material/typography": "15.0.0-canary.684e33d25.0", + "@material/density": "15.0.0-canary.3b5b55e31.0", + "@material/dom": "15.0.0-canary.3b5b55e31.0", + "@material/elevation": "15.0.0-canary.3b5b55e31.0", + "@material/feature-targeting": "15.0.0-canary.3b5b55e31.0", + "@material/focus-ring": "15.0.0-canary.3b5b55e31.0", + "@material/ripple": "15.0.0-canary.3b5b55e31.0", + "@material/rtl": "15.0.0-canary.3b5b55e31.0", + "@material/shape": "15.0.0-canary.3b5b55e31.0", + "@material/theme": "15.0.0-canary.3b5b55e31.0", + "@material/tokens": "15.0.0-canary.3b5b55e31.0", + "@material/touch-target": "15.0.0-canary.3b5b55e31.0", + "@material/typography": "15.0.0-canary.3b5b55e31.0", "tslib": "^2.1.0" } }, "node_modules/@material/card": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/card/-/card-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-xhyB7XX5KkEiCEqwSPkl58ZGYL6xFdnY62zimyBXJRG/Eaa0Swj3kW20hVCpt4f7c9Zmp8Se27rg8vnKmhvO3g==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/card/-/card-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-i0CED1wF9mUlbE0Ck57uiwKtXaSSWaHAJ45djdT0HjlLHXay3aEvyKQTjjN4+clgHjL14UiMkrSEM3/cmPs/Wg==", "dependencies": { - "@material/dom": "15.0.0-canary.684e33d25.0", - "@material/elevation": "15.0.0-canary.684e33d25.0", - "@material/feature-targeting": "15.0.0-canary.684e33d25.0", - "@material/ripple": "15.0.0-canary.684e33d25.0", - "@material/rtl": "15.0.0-canary.684e33d25.0", - "@material/shape": "15.0.0-canary.684e33d25.0", - "@material/theme": "15.0.0-canary.684e33d25.0", - "@material/tokens": "15.0.0-canary.684e33d25.0", + "@material/dom": "15.0.0-canary.3b5b55e31.0", + "@material/elevation": "15.0.0-canary.3b5b55e31.0", + "@material/feature-targeting": "15.0.0-canary.3b5b55e31.0", + "@material/ripple": "15.0.0-canary.3b5b55e31.0", + "@material/rtl": "15.0.0-canary.3b5b55e31.0", + "@material/shape": "15.0.0-canary.3b5b55e31.0", + "@material/theme": "15.0.0-canary.3b5b55e31.0", + "@material/tokens": "15.0.0-canary.3b5b55e31.0", "tslib": "^2.1.0" } }, "node_modules/@material/checkbox": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/checkbox/-/checkbox-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-NFpM3TS924PmVsk2KQLNU95OYCf8ZwYgzeqfnAexU0bEfjUJXINBun2Go0AaeOUMjuvWUe+byjrXgv8SFYbMUA==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/checkbox/-/checkbox-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-D9fod/+GYQVjryoWR4pSlXsLrUsosGOdCzlMwxmoJiwla1dUPPfEsgy4h6+ipPQ7hd8KsJ5fn7e1GArd3zzbPw==", "dependencies": { - "@material/animation": "15.0.0-canary.684e33d25.0", - "@material/base": "15.0.0-canary.684e33d25.0", - "@material/density": "15.0.0-canary.684e33d25.0", - "@material/dom": "15.0.0-canary.684e33d25.0", - "@material/feature-targeting": "15.0.0-canary.684e33d25.0", - "@material/focus-ring": "15.0.0-canary.684e33d25.0", - "@material/ripple": "15.0.0-canary.684e33d25.0", - "@material/theme": "15.0.0-canary.684e33d25.0", - "@material/touch-target": "15.0.0-canary.684e33d25.0", + "@material/animation": "15.0.0-canary.3b5b55e31.0", + "@material/base": "15.0.0-canary.3b5b55e31.0", + "@material/density": "15.0.0-canary.3b5b55e31.0", + "@material/dom": "15.0.0-canary.3b5b55e31.0", + "@material/feature-targeting": "15.0.0-canary.3b5b55e31.0", + "@material/focus-ring": "15.0.0-canary.3b5b55e31.0", + "@material/ripple": "15.0.0-canary.3b5b55e31.0", + "@material/rtl": "15.0.0-canary.3b5b55e31.0", + "@material/theme": "15.0.0-canary.3b5b55e31.0", + "@material/touch-target": "15.0.0-canary.3b5b55e31.0", "tslib": "^2.1.0" } }, "node_modules/@material/chips": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/chips/-/chips-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-z4ajQ4NnsAQ/Si9tZ4xmxzjj2Qb+vW++4QjCjjjwAGIZbCe0xglAnMh2t66XLJUxt7RoKZuZVEO7ZqcFZpvJFQ==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/chips/-/chips-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-1s4sK9iunD7lFDCd4jxQiDoY8mOlMywY3AeymsbRrzG6rObLv0AGsX5moyxhpsh/IwSSQFdW4xrtCESu+dRZbg==", "dependencies": { - "@material/animation": "15.0.0-canary.684e33d25.0", - "@material/base": "15.0.0-canary.684e33d25.0", - "@material/checkbox": "15.0.0-canary.684e33d25.0", - "@material/density": "15.0.0-canary.684e33d25.0", - "@material/dom": "15.0.0-canary.684e33d25.0", - "@material/elevation": "15.0.0-canary.684e33d25.0", - "@material/feature-targeting": "15.0.0-canary.684e33d25.0", - "@material/focus-ring": "15.0.0-canary.684e33d25.0", - "@material/ripple": "15.0.0-canary.684e33d25.0", - "@material/rtl": "15.0.0-canary.684e33d25.0", - "@material/shape": "15.0.0-canary.684e33d25.0", - "@material/theme": "15.0.0-canary.684e33d25.0", - "@material/tokens": "15.0.0-canary.684e33d25.0", - "@material/touch-target": "15.0.0-canary.684e33d25.0", - "@material/typography": "15.0.0-canary.684e33d25.0", + "@material/animation": "15.0.0-canary.3b5b55e31.0", + "@material/base": "15.0.0-canary.3b5b55e31.0", + "@material/checkbox": "15.0.0-canary.3b5b55e31.0", + "@material/density": "15.0.0-canary.3b5b55e31.0", + "@material/dom": "15.0.0-canary.3b5b55e31.0", + "@material/elevation": "15.0.0-canary.3b5b55e31.0", + "@material/feature-targeting": "15.0.0-canary.3b5b55e31.0", + "@material/focus-ring": "15.0.0-canary.3b5b55e31.0", + "@material/ripple": "15.0.0-canary.3b5b55e31.0", + "@material/rtl": "15.0.0-canary.3b5b55e31.0", + "@material/shape": "15.0.0-canary.3b5b55e31.0", + "@material/theme": "15.0.0-canary.3b5b55e31.0", + "@material/tokens": "15.0.0-canary.3b5b55e31.0", + "@material/touch-target": "15.0.0-canary.3b5b55e31.0", + "@material/typography": "15.0.0-canary.3b5b55e31.0", "safevalues": "^0.3.4", "tslib": "^2.1.0" } }, "node_modules/@material/circular-progress": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/circular-progress/-/circular-progress-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-G6qD0nGNtEUwWnAMJuA9INYFpZoKtx7KFjBaPF4Ol2YLHtmShALNAYyn54TMAK8AZ2IpW08PXjGS7Ye88vrdEQ==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/circular-progress/-/circular-progress-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-qDOtGRIkA1FGaPXqHVrckOUFWneoWqd1eosRarzNSENmpluIjfFY6DNzrJr6a1Grb82Iaui2Q2XcCVNN8pL9kA==", "dependencies": { - "@material/animation": "15.0.0-canary.684e33d25.0", - "@material/base": "15.0.0-canary.684e33d25.0", - "@material/dom": "15.0.0-canary.684e33d25.0", - "@material/feature-targeting": "15.0.0-canary.684e33d25.0", - "@material/progress-indicator": "15.0.0-canary.684e33d25.0", - "@material/rtl": "15.0.0-canary.684e33d25.0", - "@material/theme": "15.0.0-canary.684e33d25.0", + "@material/animation": "15.0.0-canary.3b5b55e31.0", + "@material/base": "15.0.0-canary.3b5b55e31.0", + "@material/dom": "15.0.0-canary.3b5b55e31.0", + "@material/feature-targeting": "15.0.0-canary.3b5b55e31.0", + "@material/progress-indicator": "15.0.0-canary.3b5b55e31.0", + "@material/rtl": "15.0.0-canary.3b5b55e31.0", + "@material/theme": "15.0.0-canary.3b5b55e31.0", "tslib": "^2.1.0" } }, "node_modules/@material/data-table": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/data-table/-/data-table-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-+wDw1DDDFfAsKAMzs84f/5GCjux39zjNfW8tL4wFbkWNwewmQrG9zaQMJhBpVOtLCrM8Gj6SOgOANqgqoCjvGg==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/data-table/-/data-table-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-xlxN6U7wspzzaN7zuxYhmFxpMyL5onBJfaL2LfMiCa8BwaBcDOxXj4nXIQ8CIsZYBpvCFaCRrLx5iS/eIqhQNQ==", "dependencies": { - "@material/animation": "15.0.0-canary.684e33d25.0", - "@material/base": "15.0.0-canary.684e33d25.0", - "@material/checkbox": "15.0.0-canary.684e33d25.0", - "@material/density": "15.0.0-canary.684e33d25.0", - "@material/dom": "15.0.0-canary.684e33d25.0", - "@material/elevation": "15.0.0-canary.684e33d25.0", - "@material/feature-targeting": "15.0.0-canary.684e33d25.0", - "@material/icon-button": "15.0.0-canary.684e33d25.0", - "@material/linear-progress": "15.0.0-canary.684e33d25.0", - "@material/list": "15.0.0-canary.684e33d25.0", - "@material/menu": "15.0.0-canary.684e33d25.0", - "@material/rtl": "15.0.0-canary.684e33d25.0", - "@material/select": "15.0.0-canary.684e33d25.0", - "@material/shape": "15.0.0-canary.684e33d25.0", - "@material/theme": "15.0.0-canary.684e33d25.0", - "@material/tokens": "15.0.0-canary.684e33d25.0", - "@material/touch-target": "15.0.0-canary.684e33d25.0", - "@material/typography": "15.0.0-canary.684e33d25.0", + "@material/animation": "15.0.0-canary.3b5b55e31.0", + "@material/base": "15.0.0-canary.3b5b55e31.0", + "@material/checkbox": "15.0.0-canary.3b5b55e31.0", + "@material/density": "15.0.0-canary.3b5b55e31.0", + "@material/dom": "15.0.0-canary.3b5b55e31.0", + "@material/elevation": "15.0.0-canary.3b5b55e31.0", + "@material/feature-targeting": "15.0.0-canary.3b5b55e31.0", + "@material/icon-button": "15.0.0-canary.3b5b55e31.0", + "@material/linear-progress": "15.0.0-canary.3b5b55e31.0", + "@material/list": "15.0.0-canary.3b5b55e31.0", + "@material/menu": "15.0.0-canary.3b5b55e31.0", + "@material/rtl": "15.0.0-canary.3b5b55e31.0", + "@material/select": "15.0.0-canary.3b5b55e31.0", + "@material/shape": "15.0.0-canary.3b5b55e31.0", + "@material/theme": "15.0.0-canary.3b5b55e31.0", + "@material/tokens": "15.0.0-canary.3b5b55e31.0", + "@material/touch-target": "15.0.0-canary.3b5b55e31.0", + "@material/typography": "15.0.0-canary.3b5b55e31.0", "tslib": "^2.1.0" } }, "node_modules/@material/density": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/density/-/density-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-661yEVRMGrlq6S6WuSbPRO+ZwpdUOg2glCc7y96doM6itSLOa3UEAldjOLfsYZVB74GnKCiuDp//QmfoRyYTfA==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/density/-/density-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-9qVFbTPiZzysa4lkPDhhcq+gOhvNBi4J5Agw7+vBzumgO8o3Msd2/fuIfv0JUv1aMyJPzWN7tsorow8pB9Ft1A==", "dependencies": { "tslib": "^2.1.0" } }, "node_modules/@material/dialog": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/dialog/-/dialog-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-szn0dHnfeQTSOC6SSRSGAzX6Tnx+4NnSMUwNkXm+3bwjds8ZVK26+DXwLrP5f3ID5F1K5sFsRf2INo5/TNTHyQ==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/dialog/-/dialog-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-cSFbYOwOHoz+U9oX7hU8L0CiLHjF0Kalu5Hd66hf2m3K6CJMcbPW8da0nubHckJwRp/POzlCCnc0zDzkHPYx8w==", "dependencies": { - "@material/animation": "15.0.0-canary.684e33d25.0", - "@material/base": "15.0.0-canary.684e33d25.0", - "@material/button": "15.0.0-canary.684e33d25.0", - "@material/dom": "15.0.0-canary.684e33d25.0", - "@material/elevation": "15.0.0-canary.684e33d25.0", - "@material/feature-targeting": "15.0.0-canary.684e33d25.0", - "@material/icon-button": "15.0.0-canary.684e33d25.0", - "@material/ripple": "15.0.0-canary.684e33d25.0", - "@material/rtl": "15.0.0-canary.684e33d25.0", - "@material/shape": "15.0.0-canary.684e33d25.0", - "@material/theme": "15.0.0-canary.684e33d25.0", - "@material/tokens": "15.0.0-canary.684e33d25.0", - "@material/touch-target": "15.0.0-canary.684e33d25.0", - "@material/typography": "15.0.0-canary.684e33d25.0", + "@material/animation": "15.0.0-canary.3b5b55e31.0", + "@material/base": "15.0.0-canary.3b5b55e31.0", + "@material/button": "15.0.0-canary.3b5b55e31.0", + "@material/dom": "15.0.0-canary.3b5b55e31.0", + "@material/elevation": "15.0.0-canary.3b5b55e31.0", + "@material/feature-targeting": "15.0.0-canary.3b5b55e31.0", + "@material/icon-button": "15.0.0-canary.3b5b55e31.0", + "@material/ripple": "15.0.0-canary.3b5b55e31.0", + "@material/rtl": "15.0.0-canary.3b5b55e31.0", + "@material/shape": "15.0.0-canary.3b5b55e31.0", + "@material/theme": "15.0.0-canary.3b5b55e31.0", + "@material/tokens": "15.0.0-canary.3b5b55e31.0", + "@material/touch-target": "15.0.0-canary.3b5b55e31.0", + "@material/typography": "15.0.0-canary.3b5b55e31.0", "tslib": "^2.1.0" } }, "node_modules/@material/dom": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/dom/-/dom-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-7pEJLYov+tGgfuD8mZxoVU6rWtPI8ppjTAhz+F27Hz9FG0JETMWTKpDPBXLnKvX7vhIxL83GvZ9geNHCe8Hfog==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/dom/-/dom-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-3bZN0pJUatMNIRULlMqHOdS/Ewh9Skbe1CUojKlk0voge2n1BRgZAdW1rbArEQs4mLN5RW1oABUHhFn6nCP+xg==", "dependencies": { - "@material/feature-targeting": "15.0.0-canary.684e33d25.0", - "@material/rtl": "15.0.0-canary.684e33d25.0", + "@material/feature-targeting": "15.0.0-canary.3b5b55e31.0", + "@material/rtl": "15.0.0-canary.3b5b55e31.0", "tslib": "^2.1.0" } }, "node_modules/@material/drawer": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/drawer/-/drawer-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-/KMckLf1PYU/H3PXnS4e0aFl03qG3JlSv4LGgX6juJufcONqGTl/m63EMO/L/eUy6H1CRrXmVDjik/jzHLyDhg==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/drawer/-/drawer-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-ZwrihhH5M+ioEmnc84st5u2E9x+9bMGPw+yyxglcchtTMA+H87VlcngQgX8qf2fwgEGp2nv6SVXnh9lQya811Q==", "dependencies": { - "@material/animation": "15.0.0-canary.684e33d25.0", - "@material/base": "15.0.0-canary.684e33d25.0", - "@material/dom": "15.0.0-canary.684e33d25.0", - "@material/elevation": "15.0.0-canary.684e33d25.0", - "@material/feature-targeting": "15.0.0-canary.684e33d25.0", - "@material/list": "15.0.0-canary.684e33d25.0", - "@material/ripple": "15.0.0-canary.684e33d25.0", - "@material/rtl": "15.0.0-canary.684e33d25.0", - "@material/shape": "15.0.0-canary.684e33d25.0", - "@material/theme": "15.0.0-canary.684e33d25.0", - "@material/typography": "15.0.0-canary.684e33d25.0", + "@material/animation": "15.0.0-canary.3b5b55e31.0", + "@material/base": "15.0.0-canary.3b5b55e31.0", + "@material/dom": "15.0.0-canary.3b5b55e31.0", + "@material/elevation": "15.0.0-canary.3b5b55e31.0", + "@material/feature-targeting": "15.0.0-canary.3b5b55e31.0", + "@material/list": "15.0.0-canary.3b5b55e31.0", + "@material/ripple": "15.0.0-canary.3b5b55e31.0", + "@material/rtl": "15.0.0-canary.3b5b55e31.0", + "@material/shape": "15.0.0-canary.3b5b55e31.0", + "@material/theme": "15.0.0-canary.3b5b55e31.0", + "@material/typography": "15.0.0-canary.3b5b55e31.0", "tslib": "^2.1.0" } }, "node_modules/@material/elevation": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/elevation/-/elevation-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-WDF8SsRtq3rXUbVVbd9K4DUijIPH0bUFSOreVYxudpuxAfTlDS5+aeS1EK9UIBFYLuba4u5wVT2tDv6e1RTfrQ==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/elevation/-/elevation-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-DPmxmCc9nUMhKw4il6pSL00oYyiti3QopfHeq6Fr8qT4hevfzV7tjm0vFbUaQtr4X0/y7WV6SrRDMMWanQkHUg==", "dependencies": { - "@material/animation": "15.0.0-canary.684e33d25.0", - "@material/base": "15.0.0-canary.684e33d25.0", - "@material/feature-targeting": "15.0.0-canary.684e33d25.0", - "@material/rtl": "15.0.0-canary.684e33d25.0", - "@material/theme": "15.0.0-canary.684e33d25.0", + "@material/animation": "15.0.0-canary.3b5b55e31.0", + "@material/base": "15.0.0-canary.3b5b55e31.0", + "@material/feature-targeting": "15.0.0-canary.3b5b55e31.0", + "@material/rtl": "15.0.0-canary.3b5b55e31.0", + "@material/theme": "15.0.0-canary.3b5b55e31.0", "tslib": "^2.1.0" } }, "node_modules/@material/fab": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/fab/-/fab-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-KCu87rWOKEAe9vZcAm6K8XazYSWPNjMG+OhrbPjHW6bCO7as1YCgtmkBkhff7csY/rFmcVpIy884xtUfLmSudQ==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/fab/-/fab-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-i4p05wgkgUj7isE3Hvlq2Q9knG75AR4GG4259qQNgmcUYJBdmV0vro7RVQL4/majo99rQbhdi0fMzgacJllZgw==", "dependencies": { - "@material/animation": "15.0.0-canary.684e33d25.0", - "@material/dom": "15.0.0-canary.684e33d25.0", - "@material/elevation": "15.0.0-canary.684e33d25.0", - "@material/feature-targeting": "15.0.0-canary.684e33d25.0", - "@material/focus-ring": "15.0.0-canary.684e33d25.0", - "@material/ripple": "15.0.0-canary.684e33d25.0", - "@material/rtl": "15.0.0-canary.684e33d25.0", - "@material/shape": "15.0.0-canary.684e33d25.0", - "@material/theme": "15.0.0-canary.684e33d25.0", - "@material/tokens": "15.0.0-canary.684e33d25.0", - "@material/touch-target": "15.0.0-canary.684e33d25.0", - "@material/typography": "15.0.0-canary.684e33d25.0", + "@material/animation": "15.0.0-canary.3b5b55e31.0", + "@material/dom": "15.0.0-canary.3b5b55e31.0", + "@material/elevation": "15.0.0-canary.3b5b55e31.0", + "@material/feature-targeting": "15.0.0-canary.3b5b55e31.0", + "@material/focus-ring": "15.0.0-canary.3b5b55e31.0", + "@material/ripple": "15.0.0-canary.3b5b55e31.0", + "@material/rtl": "15.0.0-canary.3b5b55e31.0", + "@material/shape": "15.0.0-canary.3b5b55e31.0", + "@material/theme": "15.0.0-canary.3b5b55e31.0", + "@material/tokens": "15.0.0-canary.3b5b55e31.0", + "@material/touch-target": "15.0.0-canary.3b5b55e31.0", + "@material/typography": "15.0.0-canary.3b5b55e31.0", "tslib": "^2.1.0" } }, "node_modules/@material/feature-targeting": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/feature-targeting/-/feature-targeting-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-HyH1erNTSjS63sigNSUMaCd0nJhTNdDFeC+myrxwtDaQm+uYJ8troCNtQM3g6mx0XATNtX5aTOoPmrM6yVVi1A==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/feature-targeting/-/feature-targeting-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-ZOlpc4s/myUYb+3qP1t+XFFZP5oPYe7R4kXU8N0roG3XXk0RkxiTI8nje2a8Z1HbLIcHHbCtwiPj+STHIYt8tA==", "dependencies": { "tslib": "^2.1.0" } }, "node_modules/@material/floating-label": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/floating-label/-/floating-label-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-f7TPp6bKpGvV3sYYiZHSGlrixXKkXXITW3Esp7KB9jRq42c0H82novmdwvY0eTef4ootmA2JEysr78KQfHBUPg==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/floating-label/-/floating-label-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-YJhfh19zXDKzj0z7RrbZOOnlF5ZIpqIikNEq81VKn78TiiQOe+5x+D2lGfep+tqYf8lJk/zxhtOv55L9755QWQ==", "dependencies": { - "@material/animation": "15.0.0-canary.684e33d25.0", - "@material/base": "15.0.0-canary.684e33d25.0", - "@material/dom": "15.0.0-canary.684e33d25.0", - "@material/feature-targeting": "15.0.0-canary.684e33d25.0", - "@material/rtl": "15.0.0-canary.684e33d25.0", - "@material/theme": "15.0.0-canary.684e33d25.0", - "@material/typography": "15.0.0-canary.684e33d25.0", + "@material/animation": "15.0.0-canary.3b5b55e31.0", + "@material/base": "15.0.0-canary.3b5b55e31.0", + "@material/dom": "15.0.0-canary.3b5b55e31.0", + "@material/feature-targeting": "15.0.0-canary.3b5b55e31.0", + "@material/rtl": "15.0.0-canary.3b5b55e31.0", + "@material/theme": "15.0.0-canary.3b5b55e31.0", + "@material/typography": "15.0.0-canary.3b5b55e31.0", "tslib": "^2.1.0" } }, "node_modules/@material/focus-ring": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/focus-ring/-/focus-ring-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-ikw2RVUfgzXChpWIzPH1VzRvTjYb5ZKj4H+CZf7jqPUXMstFOZg90Bp7ARLZHqYiyNMuUq3zUTHozS6iHorSqg==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/focus-ring/-/focus-ring-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-psrOK7/VN0DtwzJP5a976pqCzqjqwFNFCPuTJxyfrEfhjblAXJhgOVWx8Mm9w7cEB4RuNxNLyhVPKp3kPuIHFw==", "dependencies": { - "@material/dom": "15.0.0-canary.684e33d25.0", - "@material/feature-targeting": "15.0.0-canary.684e33d25.0", - "@material/rtl": "15.0.0-canary.684e33d25.0" + "@material/dom": "15.0.0-canary.3b5b55e31.0", + "@material/feature-targeting": "15.0.0-canary.3b5b55e31.0", + "@material/rtl": "15.0.0-canary.3b5b55e31.0" } }, "node_modules/@material/form-field": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/form-field/-/form-field-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-vpF9N/uq5no/7+8GAbEH0868FhOuBgxAWRr1Sfb+jthKfBr8OS/wPU/AHzZHdHdAm7PQynbeOXfDsX2dI//PDA==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/form-field/-/form-field-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-/ad0Q8udNtEiPhIMVT1XCf886McDxo3KscH6/v9OJrqrgfVYf052/VjJG4ltTl1DyblT9CVH+syXWh++Y1d6Dg==", "dependencies": { - "@material/base": "15.0.0-canary.684e33d25.0", - "@material/feature-targeting": "15.0.0-canary.684e33d25.0", - "@material/ripple": "15.0.0-canary.684e33d25.0", - "@material/rtl": "15.0.0-canary.684e33d25.0", - "@material/theme": "15.0.0-canary.684e33d25.0", - "@material/typography": "15.0.0-canary.684e33d25.0", + "@material/base": "15.0.0-canary.3b5b55e31.0", + "@material/feature-targeting": "15.0.0-canary.3b5b55e31.0", + "@material/ripple": "15.0.0-canary.3b5b55e31.0", + "@material/rtl": "15.0.0-canary.3b5b55e31.0", + "@material/theme": "15.0.0-canary.3b5b55e31.0", + "@material/typography": "15.0.0-canary.3b5b55e31.0", "tslib": "^2.1.0" } }, "node_modules/@material/icon-button": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/icon-button/-/icon-button-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-wMI+XGzmIN/o2ePBKg2hLyx7H4pXCRAyyIKMQS1FMp1UKa2tYmiHVX/V8skhKwCqxg3i6Ls/LxMjfPxTR18WvQ==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/icon-button/-/icon-button-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-MHn/R18YjXH4UIOnZPIcDa1VKTuU/KbXIHaMoLDXDo4QfISoQLs6AbxgK77l6rmFACRi8MHKhRJ8LAdKKUF38w==", "dependencies": { - "@material/base": "15.0.0-canary.684e33d25.0", - "@material/density": "15.0.0-canary.684e33d25.0", - "@material/dom": "15.0.0-canary.684e33d25.0", - "@material/elevation": "15.0.0-canary.684e33d25.0", - "@material/feature-targeting": "15.0.0-canary.684e33d25.0", - "@material/focus-ring": "15.0.0-canary.684e33d25.0", - "@material/ripple": "15.0.0-canary.684e33d25.0", - "@material/rtl": "15.0.0-canary.684e33d25.0", - "@material/theme": "15.0.0-canary.684e33d25.0", - "@material/touch-target": "15.0.0-canary.684e33d25.0", + "@material/base": "15.0.0-canary.3b5b55e31.0", + "@material/density": "15.0.0-canary.3b5b55e31.0", + "@material/dom": "15.0.0-canary.3b5b55e31.0", + "@material/elevation": "15.0.0-canary.3b5b55e31.0", + "@material/feature-targeting": "15.0.0-canary.3b5b55e31.0", + "@material/focus-ring": "15.0.0-canary.3b5b55e31.0", + "@material/ripple": "15.0.0-canary.3b5b55e31.0", + "@material/rtl": "15.0.0-canary.3b5b55e31.0", + "@material/theme": "15.0.0-canary.3b5b55e31.0", + "@material/touch-target": "15.0.0-canary.3b5b55e31.0", "tslib": "^2.1.0" } }, "node_modules/@material/image-list": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/image-list/-/image-list-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-Ol+uaHYBe5R/cgzlfh5ONnMVX0wO6fV74JMUcQCQlxP6lXau/edARo4tkRc7A7UJUkU3VRv0EpEjLoCRNUPGaA==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/image-list/-/image-list-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-tqvCXRfX5d5y9lK7MgP0tbtGvKlTyS1i5BAhYl4PyFY8dFTrTkEU8b2FjcTLby+AJGKSY/EkeWZw8g4YJb0eig==", "dependencies": { - "@material/feature-targeting": "15.0.0-canary.684e33d25.0", - "@material/shape": "15.0.0-canary.684e33d25.0", - "@material/theme": "15.0.0-canary.684e33d25.0", - "@material/typography": "15.0.0-canary.684e33d25.0", + "@material/feature-targeting": "15.0.0-canary.3b5b55e31.0", + "@material/shape": "15.0.0-canary.3b5b55e31.0", + "@material/theme": "15.0.0-canary.3b5b55e31.0", + "@material/typography": "15.0.0-canary.3b5b55e31.0", "tslib": "^2.1.0" } }, "node_modules/@material/layout-grid": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/layout-grid/-/layout-grid-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-ALXE1mqFNb/RB2lVRQ3/r1Aufw2mFZnOjRE+boYDVepmAG/xWyPCyaGoavELJF5l4GAb0tXi8wA/8HeGbLOpuA==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/layout-grid/-/layout-grid-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-m1LxCfPYBkCzBVO35/lMRqvi25HLPi8m7rYpWKRvihz8vIMRRlmBsHkvdWahtN1dbQ7eOUOCjgaqM21XFeOzIA==", "dependencies": { "tslib": "^2.1.0" } }, "node_modules/@material/line-ripple": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/line-ripple/-/line-ripple-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-7hRx8C/e9i0P6pgQpNOMfTwSS2r1fwEvBL72QDVGLtLuoKKwsjjgP6Z0Jat/GeHJe87u9LQvGBoD4upt+of/HA==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/line-ripple/-/line-ripple-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-p92jxhnw7bw9Sxx7P4uTy/mTxQ3+q7uZlRoRy+JtN6y9yEmZ2eqexEjf7IDQEvotHsLam7PKstg2h0X9CtujmA==", "dependencies": { - "@material/animation": "15.0.0-canary.684e33d25.0", - "@material/base": "15.0.0-canary.684e33d25.0", - "@material/feature-targeting": "15.0.0-canary.684e33d25.0", - "@material/theme": "15.0.0-canary.684e33d25.0", + "@material/animation": "15.0.0-canary.3b5b55e31.0", + "@material/base": "15.0.0-canary.3b5b55e31.0", + "@material/feature-targeting": "15.0.0-canary.3b5b55e31.0", + "@material/theme": "15.0.0-canary.3b5b55e31.0", "tslib": "^2.1.0" } }, "node_modules/@material/linear-progress": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/linear-progress/-/linear-progress-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-iJclt7mKmcMk6pqD7ocXKfCWZhqBoODp7N593jYlxVpTJuEz2wiVAjZUDn/YGj/Uz3CRH+2YFfOiLr9pwWjhDg==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/linear-progress/-/linear-progress-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-Ws3h1iHyHHefHFkFm6t8ORzRs3UdgjjhslLNVB1oHYLWZj2vRizDUuB4aIGbjfTG9UTil8wn6ub9MsyFuH1XQg==", "dependencies": { - "@material/animation": "15.0.0-canary.684e33d25.0", - "@material/base": "15.0.0-canary.684e33d25.0", - "@material/dom": "15.0.0-canary.684e33d25.0", - "@material/feature-targeting": "15.0.0-canary.684e33d25.0", - "@material/progress-indicator": "15.0.0-canary.684e33d25.0", - "@material/rtl": "15.0.0-canary.684e33d25.0", - "@material/theme": "15.0.0-canary.684e33d25.0", + "@material/animation": "15.0.0-canary.3b5b55e31.0", + "@material/base": "15.0.0-canary.3b5b55e31.0", + "@material/dom": "15.0.0-canary.3b5b55e31.0", + "@material/feature-targeting": "15.0.0-canary.3b5b55e31.0", + "@material/progress-indicator": "15.0.0-canary.3b5b55e31.0", + "@material/rtl": "15.0.0-canary.3b5b55e31.0", + "@material/theme": "15.0.0-canary.3b5b55e31.0", "tslib": "^2.1.0" } }, "node_modules/@material/list": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/list/-/list-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-rQ+FCSdzmwTcT00IYE0uRV3CS4oGSccKFl9hkcF+aHFW61L7ORh/SCGUDPrEfQFrFkMn5f8qroVJjpUAMXBz4g==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/list/-/list-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-xy3PY6RQRCjnO5SuhSaLn2YO4rAU+JZDyDx9Uyx4bfZ+Pgzpst3ji/rbTOtM9sqNoixGWF6SH/e+GlqmVSm9zg==", "dependencies": { - "@material/base": "15.0.0-canary.684e33d25.0", - "@material/density": "15.0.0-canary.684e33d25.0", - "@material/dom": "15.0.0-canary.684e33d25.0", - "@material/feature-targeting": "15.0.0-canary.684e33d25.0", - "@material/ripple": "15.0.0-canary.684e33d25.0", - "@material/rtl": "15.0.0-canary.684e33d25.0", - "@material/shape": "15.0.0-canary.684e33d25.0", - "@material/theme": "15.0.0-canary.684e33d25.0", - "@material/tokens": "15.0.0-canary.684e33d25.0", - "@material/typography": "15.0.0-canary.684e33d25.0", + "@material/base": "15.0.0-canary.3b5b55e31.0", + "@material/density": "15.0.0-canary.3b5b55e31.0", + "@material/dom": "15.0.0-canary.3b5b55e31.0", + "@material/feature-targeting": "15.0.0-canary.3b5b55e31.0", + "@material/ripple": "15.0.0-canary.3b5b55e31.0", + "@material/rtl": "15.0.0-canary.3b5b55e31.0", + "@material/shape": "15.0.0-canary.3b5b55e31.0", + "@material/theme": "15.0.0-canary.3b5b55e31.0", + "@material/tokens": "15.0.0-canary.3b5b55e31.0", + "@material/typography": "15.0.0-canary.3b5b55e31.0", "tslib": "^2.1.0" } }, "node_modules/@material/menu": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/menu/-/menu-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-r7wzDLSGSI9629/mfpvsMzkVxpmV75kcD3IrW0Pcu6/Bv/1xi0EvjcUXzNJJoQlwN4Zj35Ymz/PCjZkIDIz68Q==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/menu/-/menu-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-SfA67F7rmUzOWqzpywcbQlZtaZ/UVdXkalS98z3+xWkd+f/KBWZx3HBZLHSjLeablERayZCRCl8U6cwbjtq9Ig==", "dependencies": { - "@material/base": "15.0.0-canary.684e33d25.0", - "@material/dom": "15.0.0-canary.684e33d25.0", - "@material/elevation": "15.0.0-canary.684e33d25.0", - "@material/feature-targeting": "15.0.0-canary.684e33d25.0", - "@material/list": "15.0.0-canary.684e33d25.0", - "@material/menu-surface": "15.0.0-canary.684e33d25.0", - "@material/ripple": "15.0.0-canary.684e33d25.0", - "@material/rtl": "15.0.0-canary.684e33d25.0", - "@material/shape": "15.0.0-canary.684e33d25.0", - "@material/theme": "15.0.0-canary.684e33d25.0", - "@material/tokens": "15.0.0-canary.684e33d25.0", + "@material/base": "15.0.0-canary.3b5b55e31.0", + "@material/dom": "15.0.0-canary.3b5b55e31.0", + "@material/elevation": "15.0.0-canary.3b5b55e31.0", + "@material/feature-targeting": "15.0.0-canary.3b5b55e31.0", + "@material/list": "15.0.0-canary.3b5b55e31.0", + "@material/menu-surface": "15.0.0-canary.3b5b55e31.0", + "@material/ripple": "15.0.0-canary.3b5b55e31.0", + "@material/rtl": "15.0.0-canary.3b5b55e31.0", + "@material/shape": "15.0.0-canary.3b5b55e31.0", + "@material/theme": "15.0.0-canary.3b5b55e31.0", + "@material/tokens": "15.0.0-canary.3b5b55e31.0", "tslib": "^2.1.0" } }, "node_modules/@material/menu-surface": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/menu-surface/-/menu-surface-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-RVO5GAYcfWPaKwxsF/NhUAmrYXQCQBKvRQW0TIlbmAJz6lcFeTs6YZqF3u1C7qrL3ZQGz+sur/7ywj6QU0oMow==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/menu-surface/-/menu-surface-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-GPJeWN0dbB8kDyRpD3kAeYU7DbJPVK0B4zR35K5snKRZZ1V6uTYQfdeCjzZgSU5ivfH4/jxGS9NK/7SnVykOxg==", "dependencies": { - "@material/animation": "15.0.0-canary.684e33d25.0", - "@material/base": "15.0.0-canary.684e33d25.0", - "@material/elevation": "15.0.0-canary.684e33d25.0", - "@material/feature-targeting": "15.0.0-canary.684e33d25.0", - "@material/rtl": "15.0.0-canary.684e33d25.0", - "@material/shape": "15.0.0-canary.684e33d25.0", - "@material/theme": "15.0.0-canary.684e33d25.0", + "@material/animation": "15.0.0-canary.3b5b55e31.0", + "@material/base": "15.0.0-canary.3b5b55e31.0", + "@material/elevation": "15.0.0-canary.3b5b55e31.0", + "@material/feature-targeting": "15.0.0-canary.3b5b55e31.0", + "@material/rtl": "15.0.0-canary.3b5b55e31.0", + "@material/shape": "15.0.0-canary.3b5b55e31.0", + "@material/theme": "15.0.0-canary.3b5b55e31.0", "tslib": "^2.1.0" } }, "node_modules/@material/notched-outline": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/notched-outline/-/notched-outline-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-9YHcBkvJLPVYzkHcWoTpBZAFrEd+j1hjhGxLhh0LuNrZe8VroUkZD1TTnUAPHRG3os6EqEWWaKb0RN+aPIF2yQ==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/notched-outline/-/notched-outline-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-rEzFUqaJJ1hX4k7TlWjGONqTeUP+IuIGiGSXnHlYdQRQQiuHTOrwI6b+l8FXgNFMmKMzg6Xzh8sr9jiV+cO5Xg==", "dependencies": { - "@material/base": "15.0.0-canary.684e33d25.0", - "@material/feature-targeting": "15.0.0-canary.684e33d25.0", - "@material/floating-label": "15.0.0-canary.684e33d25.0", - "@material/rtl": "15.0.0-canary.684e33d25.0", - "@material/shape": "15.0.0-canary.684e33d25.0", - "@material/theme": "15.0.0-canary.684e33d25.0", + "@material/base": "15.0.0-canary.3b5b55e31.0", + "@material/feature-targeting": "15.0.0-canary.3b5b55e31.0", + "@material/floating-label": "15.0.0-canary.3b5b55e31.0", + "@material/rtl": "15.0.0-canary.3b5b55e31.0", + "@material/shape": "15.0.0-canary.3b5b55e31.0", + "@material/theme": "15.0.0-canary.3b5b55e31.0", "tslib": "^2.1.0" } }, "node_modules/@material/progress-indicator": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/progress-indicator/-/progress-indicator-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-c0icji4faeNWUoqGENGC7Hav0Puxh0RwXIDVizffaUxKIGbajpIp5+4Zop73fK/xFLGMB/npg7TbP+aCGjQ3fw==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/progress-indicator/-/progress-indicator-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-WY1y0qzVv3DMNNEuQMF/EPbHIrwKbnlpOu/RRDo86D/oa9qmZP8mHe00quopWf9ZduTna2BjTWsQBid1680jAg==", "dependencies": { "tslib": "^2.1.0" } }, "node_modules/@material/radio": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/radio/-/radio-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-U3Eh8sNUA8trDla1Bq8Bo02foxYvtoewaKeF8A8tAju81XZ4jRiftfOsOWZDZEHCVbbCB2QwvutvFlnay5n+Aw==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/radio/-/radio-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-JUvJHfAMjTdcsWF5XFnRlvRKTfWmANfU86QouOH9rxY9NYqP9AROR9X/y/A6cE4TMhOdskt4+/ewl9wriSHUUw==", "dependencies": { - "@material/animation": "15.0.0-canary.684e33d25.0", - "@material/base": "15.0.0-canary.684e33d25.0", - "@material/density": "15.0.0-canary.684e33d25.0", - "@material/dom": "15.0.0-canary.684e33d25.0", - "@material/feature-targeting": "15.0.0-canary.684e33d25.0", - "@material/focus-ring": "15.0.0-canary.684e33d25.0", - "@material/ripple": "15.0.0-canary.684e33d25.0", - "@material/theme": "15.0.0-canary.684e33d25.0", - "@material/touch-target": "15.0.0-canary.684e33d25.0", + "@material/animation": "15.0.0-canary.3b5b55e31.0", + "@material/base": "15.0.0-canary.3b5b55e31.0", + "@material/density": "15.0.0-canary.3b5b55e31.0", + "@material/dom": "15.0.0-canary.3b5b55e31.0", + "@material/feature-targeting": "15.0.0-canary.3b5b55e31.0", + "@material/focus-ring": "15.0.0-canary.3b5b55e31.0", + "@material/ripple": "15.0.0-canary.3b5b55e31.0", + "@material/theme": "15.0.0-canary.3b5b55e31.0", + "@material/touch-target": "15.0.0-canary.3b5b55e31.0", "tslib": "^2.1.0" } }, "node_modules/@material/ripple": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/ripple/-/ripple-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-RyePu7SjIm/OuyyEieZ/gxiPYkNZOZHeid72WRcN9ofdlljj2pifcdPvcfZA+v/DMS33xo5GjG2L/Qj6ClWrKw==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/ripple/-/ripple-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-nrce9Qhinq64U2Ld8htuiCtBgSOxeDu+BIi0Red4oicmhTskSaOzC7NS8wjy5Q155YrnaBTsxPJZDjiTsG9e+g==", "dependencies": { - "@material/animation": "15.0.0-canary.684e33d25.0", - "@material/base": "15.0.0-canary.684e33d25.0", - "@material/dom": "15.0.0-canary.684e33d25.0", - "@material/feature-targeting": "15.0.0-canary.684e33d25.0", - "@material/rtl": "15.0.0-canary.684e33d25.0", - "@material/theme": "15.0.0-canary.684e33d25.0", + "@material/animation": "15.0.0-canary.3b5b55e31.0", + "@material/base": "15.0.0-canary.3b5b55e31.0", + "@material/dom": "15.0.0-canary.3b5b55e31.0", + "@material/feature-targeting": "15.0.0-canary.3b5b55e31.0", + "@material/rtl": "15.0.0-canary.3b5b55e31.0", + "@material/theme": "15.0.0-canary.3b5b55e31.0", "tslib": "^2.1.0" } }, "node_modules/@material/rtl": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/rtl/-/rtl-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-NqdJl8Ayupp1Th+vCNCpVQHbUFOuF7TCte9LD1norTIBUF/QizIxWby2W5uUEiPbnh5j9PmE1CJtfLwKun3pcw==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/rtl/-/rtl-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-lSp3UbhYXuW8p3qsqvft+eLxECpKH5xNL4oXc47sH9DsdSFrhFHTCeOtHwz261cMBetAXCaXsz/0BsBOslWoBg==", "dependencies": { - "@material/theme": "15.0.0-canary.684e33d25.0", + "@material/theme": "15.0.0-canary.3b5b55e31.0", "tslib": "^2.1.0" } }, "node_modules/@material/segmented-button": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/segmented-button/-/segmented-button-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-bEGgg8vgXNLyukyV8HRjFMuQ6t6nm5LQ4Pgm22um61Yc8qyi0BOqV41OR4SVdUrUqZxh1aVD+p+4NN03+LfQXw==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/segmented-button/-/segmented-button-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-62vr5OhWvf4MzVGx3L8D+wK7IzI+a5wAvW/wkcPOvm4FldTyPiey74zC84Wj8CK82UQqzYJj5jTV5KfOk/2t0w==", "dependencies": { - "@material/base": "15.0.0-canary.684e33d25.0", - "@material/elevation": "15.0.0-canary.684e33d25.0", - "@material/feature-targeting": "15.0.0-canary.684e33d25.0", - "@material/ripple": "15.0.0-canary.684e33d25.0", - "@material/theme": "15.0.0-canary.684e33d25.0", - "@material/touch-target": "15.0.0-canary.684e33d25.0", - "@material/typography": "15.0.0-canary.684e33d25.0", + "@material/base": "15.0.0-canary.3b5b55e31.0", + "@material/elevation": "15.0.0-canary.3b5b55e31.0", + "@material/feature-targeting": "15.0.0-canary.3b5b55e31.0", + "@material/ripple": "15.0.0-canary.3b5b55e31.0", + "@material/theme": "15.0.0-canary.3b5b55e31.0", + "@material/touch-target": "15.0.0-canary.3b5b55e31.0", + "@material/typography": "15.0.0-canary.3b5b55e31.0", "tslib": "^2.1.0" } }, "node_modules/@material/select": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/select/-/select-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-kf178/2TeEinTv0mgmSBcmmExQ2h7a7dtR1E3WuqQgisJ/R6+zVLMkC2CnfIyzxYX2vkuUTG0ue3Reh/6XiqSg==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/select/-/select-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-2vDCOszy5Len3XQizbEPfoaQZWSFXydc06Tbw6cNzISeHfwAU4LA3aQ9lP7vaukRBthAdy7+o7WHnrnbfVIvZQ==", "dependencies": { - "@material/animation": "15.0.0-canary.684e33d25.0", - "@material/base": "15.0.0-canary.684e33d25.0", - "@material/density": "15.0.0-canary.684e33d25.0", - "@material/dom": "15.0.0-canary.684e33d25.0", - "@material/elevation": "15.0.0-canary.684e33d25.0", - "@material/feature-targeting": "15.0.0-canary.684e33d25.0", - "@material/floating-label": "15.0.0-canary.684e33d25.0", - "@material/line-ripple": "15.0.0-canary.684e33d25.0", - "@material/list": "15.0.0-canary.684e33d25.0", - "@material/menu": "15.0.0-canary.684e33d25.0", - "@material/menu-surface": "15.0.0-canary.684e33d25.0", - "@material/notched-outline": "15.0.0-canary.684e33d25.0", - "@material/ripple": "15.0.0-canary.684e33d25.0", - "@material/rtl": "15.0.0-canary.684e33d25.0", - "@material/shape": "15.0.0-canary.684e33d25.0", - "@material/theme": "15.0.0-canary.684e33d25.0", - "@material/tokens": "15.0.0-canary.684e33d25.0", - "@material/typography": "15.0.0-canary.684e33d25.0", + "@material/animation": "15.0.0-canary.3b5b55e31.0", + "@material/base": "15.0.0-canary.3b5b55e31.0", + "@material/density": "15.0.0-canary.3b5b55e31.0", + "@material/dom": "15.0.0-canary.3b5b55e31.0", + "@material/elevation": "15.0.0-canary.3b5b55e31.0", + "@material/feature-targeting": "15.0.0-canary.3b5b55e31.0", + "@material/floating-label": "15.0.0-canary.3b5b55e31.0", + "@material/line-ripple": "15.0.0-canary.3b5b55e31.0", + "@material/list": "15.0.0-canary.3b5b55e31.0", + "@material/menu": "15.0.0-canary.3b5b55e31.0", + "@material/menu-surface": "15.0.0-canary.3b5b55e31.0", + "@material/notched-outline": "15.0.0-canary.3b5b55e31.0", + "@material/ripple": "15.0.0-canary.3b5b55e31.0", + "@material/rtl": "15.0.0-canary.3b5b55e31.0", + "@material/shape": "15.0.0-canary.3b5b55e31.0", + "@material/theme": "15.0.0-canary.3b5b55e31.0", + "@material/tokens": "15.0.0-canary.3b5b55e31.0", + "@material/typography": "15.0.0-canary.3b5b55e31.0", "tslib": "^2.1.0" } }, "node_modules/@material/shape": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/shape/-/shape-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-aEelpaTFmpnCji3TUGP9bVCS/bRVjUmLTHBPZtuu1gOrUVVtJ6kYOg73dZNJF+XOoNL2yOX/LRcKwsop29tptA==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/shape/-/shape-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-7OMwJr/iWt8secMFtgtzIcMoZo8N/axgGD6yXhAc2wWbdnh0N2h6cqB+aInQeG2oPuOqO7ofEEghSC0TIh7siA==", "dependencies": { - "@material/feature-targeting": "15.0.0-canary.684e33d25.0", - "@material/rtl": "15.0.0-canary.684e33d25.0", - "@material/theme": "15.0.0-canary.684e33d25.0", + "@material/feature-targeting": "15.0.0-canary.3b5b55e31.0", + "@material/rtl": "15.0.0-canary.3b5b55e31.0", + "@material/theme": "15.0.0-canary.3b5b55e31.0", "tslib": "^2.1.0" } }, "node_modules/@material/slider": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/slider/-/slider-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-WVyK+2pSNSZmj07M2K/a3TADoQ9FBCndfNC/vE7/wGIg4dddJJK5KvQ+yruf9R2cSzTL/S1sZ5WpyyeM8E9HTw==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/slider/-/slider-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-Eu/h6pWfhVxm2t/oyQlUXyzh4x0nynvZZl2XanZ4v84Bt4eEGSwjaECQdaU+Wf6pAkwZRx5Acl3LiyV6cu8vRA==", "dependencies": { - "@material/animation": "15.0.0-canary.684e33d25.0", - "@material/base": "15.0.0-canary.684e33d25.0", - "@material/dom": "15.0.0-canary.684e33d25.0", - "@material/elevation": "15.0.0-canary.684e33d25.0", - "@material/feature-targeting": "15.0.0-canary.684e33d25.0", - "@material/ripple": "15.0.0-canary.684e33d25.0", - "@material/rtl": "15.0.0-canary.684e33d25.0", - "@material/theme": "15.0.0-canary.684e33d25.0", - "@material/tokens": "15.0.0-canary.684e33d25.0", - "@material/typography": "15.0.0-canary.684e33d25.0", + "@material/animation": "15.0.0-canary.3b5b55e31.0", + "@material/base": "15.0.0-canary.3b5b55e31.0", + "@material/dom": "15.0.0-canary.3b5b55e31.0", + "@material/elevation": "15.0.0-canary.3b5b55e31.0", + "@material/feature-targeting": "15.0.0-canary.3b5b55e31.0", + "@material/ripple": "15.0.0-canary.3b5b55e31.0", + "@material/rtl": "15.0.0-canary.3b5b55e31.0", + "@material/theme": "15.0.0-canary.3b5b55e31.0", + "@material/tokens": "15.0.0-canary.3b5b55e31.0", + "@material/typography": "15.0.0-canary.3b5b55e31.0", "tslib": "^2.1.0" } }, "node_modules/@material/snackbar": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/snackbar/-/snackbar-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-itO+DCkOannZzR1/cCHcqAm7ifhuFvXmDItNoA8qLEcAyJDJJRkhpwj3XQ01yuo9gBFcSctp7Txt7e+Hncm/Jg==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/snackbar/-/snackbar-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-gcrCpwYz+QaXqENzVYZhGKxu3i/oM/ZamumLiUORYzt/c5vtGJfSd8l7GoJOPpIyUtBCOSOjc+QRye4KrIbLuw==", "dependencies": { - "@material/animation": "15.0.0-canary.684e33d25.0", - "@material/base": "15.0.0-canary.684e33d25.0", - "@material/button": "15.0.0-canary.684e33d25.0", - "@material/dom": "15.0.0-canary.684e33d25.0", - "@material/elevation": "15.0.0-canary.684e33d25.0", - "@material/feature-targeting": "15.0.0-canary.684e33d25.0", - "@material/icon-button": "15.0.0-canary.684e33d25.0", - "@material/ripple": "15.0.0-canary.684e33d25.0", - "@material/rtl": "15.0.0-canary.684e33d25.0", - "@material/shape": "15.0.0-canary.684e33d25.0", - "@material/theme": "15.0.0-canary.684e33d25.0", - "@material/tokens": "15.0.0-canary.684e33d25.0", - "@material/typography": "15.0.0-canary.684e33d25.0", + "@material/animation": "15.0.0-canary.3b5b55e31.0", + "@material/base": "15.0.0-canary.3b5b55e31.0", + "@material/button": "15.0.0-canary.3b5b55e31.0", + "@material/dom": "15.0.0-canary.3b5b55e31.0", + "@material/elevation": "15.0.0-canary.3b5b55e31.0", + "@material/feature-targeting": "15.0.0-canary.3b5b55e31.0", + "@material/icon-button": "15.0.0-canary.3b5b55e31.0", + "@material/ripple": "15.0.0-canary.3b5b55e31.0", + "@material/rtl": "15.0.0-canary.3b5b55e31.0", + "@material/shape": "15.0.0-canary.3b5b55e31.0", + "@material/theme": "15.0.0-canary.3b5b55e31.0", + "@material/tokens": "15.0.0-canary.3b5b55e31.0", + "@material/typography": "15.0.0-canary.3b5b55e31.0", "tslib": "^2.1.0" } }, "node_modules/@material/switch": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/switch/-/switch-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-Jxi0gl92yvvZZsAPxvVHzXx2ga+T/djMow98jvEczmpUorWnAhgiCr9CsSSRoosahWyRB8NLZOxUQrACxvffjw==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/switch/-/switch-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-G83nixwYZQ0YuV4ejH2Ef097sjyHO7r5053lzTaUMJB7wpTz9eyRbtI5TIIpDl9vQ6UA55PeYMvGJWOsL/8yxw==", "dependencies": { - "@material/animation": "15.0.0-canary.684e33d25.0", - "@material/base": "15.0.0-canary.684e33d25.0", - "@material/density": "15.0.0-canary.684e33d25.0", - "@material/dom": "15.0.0-canary.684e33d25.0", - "@material/elevation": "15.0.0-canary.684e33d25.0", - "@material/feature-targeting": "15.0.0-canary.684e33d25.0", - "@material/focus-ring": "15.0.0-canary.684e33d25.0", - "@material/ripple": "15.0.0-canary.684e33d25.0", - "@material/rtl": "15.0.0-canary.684e33d25.0", - "@material/shape": "15.0.0-canary.684e33d25.0", - "@material/theme": "15.0.0-canary.684e33d25.0", - "@material/tokens": "15.0.0-canary.684e33d25.0", + "@material/animation": "15.0.0-canary.3b5b55e31.0", + "@material/base": "15.0.0-canary.3b5b55e31.0", + "@material/density": "15.0.0-canary.3b5b55e31.0", + "@material/dom": "15.0.0-canary.3b5b55e31.0", + "@material/elevation": "15.0.0-canary.3b5b55e31.0", + "@material/feature-targeting": "15.0.0-canary.3b5b55e31.0", + "@material/focus-ring": "15.0.0-canary.3b5b55e31.0", + "@material/ripple": "15.0.0-canary.3b5b55e31.0", + "@material/rtl": "15.0.0-canary.3b5b55e31.0", + "@material/shape": "15.0.0-canary.3b5b55e31.0", + "@material/theme": "15.0.0-canary.3b5b55e31.0", + "@material/tokens": "15.0.0-canary.3b5b55e31.0", "safevalues": "^0.3.4", "tslib": "^2.1.0" } }, "node_modules/@material/tab": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/tab/-/tab-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-WQL3wj9syHNcfe8KbgGGUcA34M8C/xZ+n0Fkkh8Kk6puVwaU+xqUNihsxPY6YzKpmh4PZ4oJaBdiN8zvFT1zqQ==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/tab/-/tab-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-z7R/6yD53P46LnuieANSBL04JuVSS/8P9FEDuZVqkDkEZzCPdOumTYuj6VE/c9PC5SKM6+4kAbR5deCOhzKmNA==", "dependencies": { - "@material/base": "15.0.0-canary.684e33d25.0", - "@material/elevation": "15.0.0-canary.684e33d25.0", - "@material/feature-targeting": "15.0.0-canary.684e33d25.0", - "@material/focus-ring": "15.0.0-canary.684e33d25.0", - "@material/ripple": "15.0.0-canary.684e33d25.0", - "@material/rtl": "15.0.0-canary.684e33d25.0", - "@material/tab-indicator": "15.0.0-canary.684e33d25.0", - "@material/theme": "15.0.0-canary.684e33d25.0", - "@material/tokens": "15.0.0-canary.684e33d25.0", - "@material/typography": "15.0.0-canary.684e33d25.0", + "@material/base": "15.0.0-canary.3b5b55e31.0", + "@material/elevation": "15.0.0-canary.3b5b55e31.0", + "@material/feature-targeting": "15.0.0-canary.3b5b55e31.0", + "@material/focus-ring": "15.0.0-canary.3b5b55e31.0", + "@material/ripple": "15.0.0-canary.3b5b55e31.0", + "@material/rtl": "15.0.0-canary.3b5b55e31.0", + "@material/tab-indicator": "15.0.0-canary.3b5b55e31.0", + "@material/theme": "15.0.0-canary.3b5b55e31.0", + "@material/tokens": "15.0.0-canary.3b5b55e31.0", + "@material/typography": "15.0.0-canary.3b5b55e31.0", "tslib": "^2.1.0" } }, "node_modules/@material/tab-bar": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/tab-bar/-/tab-bar-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-SW/cMaDsIGGkM1ag3A7GJRlmr8eXmObWsvitQJzh6Azr5zzZtSI+GQygkMesAEE1gbpqOVN8d40rh3H7VVIAcA==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/tab-bar/-/tab-bar-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-hUOHNzH64hAhZ6WQ+HCDradmLGVZkb06/4sPC2dh6C1aMLIhgGoa+MQ+rPXrUZiKk1zupWe2Etgtq3mpCodIyA==", "dependencies": { - "@material/animation": "15.0.0-canary.684e33d25.0", - "@material/base": "15.0.0-canary.684e33d25.0", - "@material/density": "15.0.0-canary.684e33d25.0", - "@material/elevation": "15.0.0-canary.684e33d25.0", - "@material/feature-targeting": "15.0.0-canary.684e33d25.0", - "@material/tab": "15.0.0-canary.684e33d25.0", - "@material/tab-indicator": "15.0.0-canary.684e33d25.0", - "@material/tab-scroller": "15.0.0-canary.684e33d25.0", - "@material/theme": "15.0.0-canary.684e33d25.0", - "@material/tokens": "15.0.0-canary.684e33d25.0", - "@material/typography": "15.0.0-canary.684e33d25.0", + "@material/animation": "15.0.0-canary.3b5b55e31.0", + "@material/base": "15.0.0-canary.3b5b55e31.0", + "@material/density": "15.0.0-canary.3b5b55e31.0", + "@material/elevation": "15.0.0-canary.3b5b55e31.0", + "@material/feature-targeting": "15.0.0-canary.3b5b55e31.0", + "@material/tab": "15.0.0-canary.3b5b55e31.0", + "@material/tab-indicator": "15.0.0-canary.3b5b55e31.0", + "@material/tab-scroller": "15.0.0-canary.3b5b55e31.0", + "@material/theme": "15.0.0-canary.3b5b55e31.0", + "@material/tokens": "15.0.0-canary.3b5b55e31.0", + "@material/typography": "15.0.0-canary.3b5b55e31.0", "tslib": "^2.1.0" } }, "node_modules/@material/tab-indicator": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/tab-indicator/-/tab-indicator-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-kKICqSPqOlaf0lzaFFCmuOqPXJC+cK48Qmsc+m5o6fJhkmuZRCYpIwB2JeP+uZSOq/bTH+SrPtCtnVlgWg6ksA==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/tab-indicator/-/tab-indicator-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-EEx6trwtWHaD9RE1xBskmy2hSAGe3id+PhXeMRj7TNPZ3g9aFZ/G60y0n8oGs6zg0T8KyHVZ/37fMH/QqoEttg==", "dependencies": { - "@material/animation": "15.0.0-canary.684e33d25.0", - "@material/base": "15.0.0-canary.684e33d25.0", - "@material/feature-targeting": "15.0.0-canary.684e33d25.0", - "@material/theme": "15.0.0-canary.684e33d25.0", + "@material/animation": "15.0.0-canary.3b5b55e31.0", + "@material/base": "15.0.0-canary.3b5b55e31.0", + "@material/feature-targeting": "15.0.0-canary.3b5b55e31.0", + "@material/theme": "15.0.0-canary.3b5b55e31.0", "tslib": "^2.1.0" } }, "node_modules/@material/tab-scroller": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/tab-scroller/-/tab-scroller-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-H6EU/TSiK/M2DyyORX5GEtXD9rKYxTMHC2VxsNWARPMFJGzgeW2ugYkFv+rKI1/c0bs0CJ4e+qFnOlBsQXZvyQ==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/tab-scroller/-/tab-scroller-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-5F56pIMk43c2kjcvuP3Qs98SORH+Na/q7zr/XM1rip8y/46d1231elqj4uem6TiYD5l89qjbyD+Zq6y+i2KI5g==", "dependencies": { - "@material/animation": "15.0.0-canary.684e33d25.0", - "@material/base": "15.0.0-canary.684e33d25.0", - "@material/dom": "15.0.0-canary.684e33d25.0", - "@material/feature-targeting": "15.0.0-canary.684e33d25.0", - "@material/tab": "15.0.0-canary.684e33d25.0", + "@material/animation": "15.0.0-canary.3b5b55e31.0", + "@material/base": "15.0.0-canary.3b5b55e31.0", + "@material/dom": "15.0.0-canary.3b5b55e31.0", + "@material/feature-targeting": "15.0.0-canary.3b5b55e31.0", + "@material/tab": "15.0.0-canary.3b5b55e31.0", "tslib": "^2.1.0" } }, "node_modules/@material/textfield": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/textfield/-/textfield-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-OvgpDXjvpyJTtAWskO69IDybFvDNzr9w2PN/Fk7yFm+uNVupaWz1Ew8lZ4gGslaTNSVmh2XcsvmzxcLINSiiNg==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/textfield/-/textfield-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-1nYbaHeesVmSnym6owKC1CDAmoAuhCUKVQ2JKGtnr6gFarmtT5s3ZoJaO4bISgbgN3KP291uFNl4mCqaTGcyBQ==", "dependencies": { - "@material/animation": "15.0.0-canary.684e33d25.0", - "@material/base": "15.0.0-canary.684e33d25.0", - "@material/density": "15.0.0-canary.684e33d25.0", - "@material/dom": "15.0.0-canary.684e33d25.0", - "@material/feature-targeting": "15.0.0-canary.684e33d25.0", - "@material/floating-label": "15.0.0-canary.684e33d25.0", - "@material/line-ripple": "15.0.0-canary.684e33d25.0", - "@material/notched-outline": "15.0.0-canary.684e33d25.0", - "@material/ripple": "15.0.0-canary.684e33d25.0", - "@material/rtl": "15.0.0-canary.684e33d25.0", - "@material/shape": "15.0.0-canary.684e33d25.0", - "@material/theme": "15.0.0-canary.684e33d25.0", - "@material/tokens": "15.0.0-canary.684e33d25.0", - "@material/typography": "15.0.0-canary.684e33d25.0", + "@material/animation": "15.0.0-canary.3b5b55e31.0", + "@material/base": "15.0.0-canary.3b5b55e31.0", + "@material/density": "15.0.0-canary.3b5b55e31.0", + "@material/dom": "15.0.0-canary.3b5b55e31.0", + "@material/feature-targeting": "15.0.0-canary.3b5b55e31.0", + "@material/floating-label": "15.0.0-canary.3b5b55e31.0", + "@material/line-ripple": "15.0.0-canary.3b5b55e31.0", + "@material/notched-outline": "15.0.0-canary.3b5b55e31.0", + "@material/ripple": "15.0.0-canary.3b5b55e31.0", + "@material/rtl": "15.0.0-canary.3b5b55e31.0", + "@material/shape": "15.0.0-canary.3b5b55e31.0", + "@material/theme": "15.0.0-canary.3b5b55e31.0", + "@material/tokens": "15.0.0-canary.3b5b55e31.0", + "@material/typography": "15.0.0-canary.3b5b55e31.0", "tslib": "^2.1.0" } }, "node_modules/@material/theme": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/theme/-/theme-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-AZxaXXAvRKzAi20RlMxzt2U5UmkCWyv7DMWEBXsxtG5Tk54mi1HsbVUp3fxDPTlmL7Pq8p1/DESg/o7TgRCVlw==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/theme/-/theme-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-0v0gtYG7i3JaleFbkP2SOzzD1x4y4IOcbgJanZzi9SkWf/gsVXwbxLID1eUSFIj3+jjqRBl1h2REQ5JL1FEmPg==", "dependencies": { - "@material/feature-targeting": "15.0.0-canary.684e33d25.0", + "@material/feature-targeting": "15.0.0-canary.3b5b55e31.0", "tslib": "^2.1.0" } }, "node_modules/@material/tokens": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/tokens/-/tokens-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-wVwbQOTCXDPKYPdHQHLr026y36MMFelID1CmbfRk6mSol4O8yE9U0fXcShfRDW8Qo5E3X31w9c2A6T3neJY7wQ==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/tokens/-/tokens-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-Taj1tlo6yUjDfMXQRYKgDf9lWwDpq8/0y2qxetCddyZxilZKyW2oc5lmbzkHbCpIzYG8in//JAL6pP+JaFn0MA==", "dependencies": { - "@material/elevation": "15.0.0-canary.684e33d25.0" + "@material/elevation": "15.0.0-canary.3b5b55e31.0" } }, "node_modules/@material/tooltip": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/tooltip/-/tooltip-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-dtm26QjxyQdinc8btgz6yys07b7bUW4FZgNF2EBPeGrICrPg7jf+JEvDziz5g8VMaTBQLOQRSCGy0MKuRlOjLw==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/tooltip/-/tooltip-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-WxAJ8LxMdvSKgD1tC6mX8VbhLiMxijQm+uGK5XJZIbnHHJ6GNvvj+/kY0UydsaFPpAEtkDr3X4L9v70OF+hBBg==", "dependencies": { - "@material/animation": "15.0.0-canary.684e33d25.0", - "@material/base": "15.0.0-canary.684e33d25.0", - "@material/button": "15.0.0-canary.684e33d25.0", - "@material/dom": "15.0.0-canary.684e33d25.0", - "@material/elevation": "15.0.0-canary.684e33d25.0", - "@material/feature-targeting": "15.0.0-canary.684e33d25.0", - "@material/rtl": "15.0.0-canary.684e33d25.0", - "@material/shape": "15.0.0-canary.684e33d25.0", - "@material/theme": "15.0.0-canary.684e33d25.0", - "@material/tokens": "15.0.0-canary.684e33d25.0", - "@material/typography": "15.0.0-canary.684e33d25.0", + "@material/animation": "15.0.0-canary.3b5b55e31.0", + "@material/base": "15.0.0-canary.3b5b55e31.0", + "@material/button": "15.0.0-canary.3b5b55e31.0", + "@material/dom": "15.0.0-canary.3b5b55e31.0", + "@material/elevation": "15.0.0-canary.3b5b55e31.0", + "@material/feature-targeting": "15.0.0-canary.3b5b55e31.0", + "@material/rtl": "15.0.0-canary.3b5b55e31.0", + "@material/shape": "15.0.0-canary.3b5b55e31.0", + "@material/theme": "15.0.0-canary.3b5b55e31.0", + "@material/tokens": "15.0.0-canary.3b5b55e31.0", + "@material/typography": "15.0.0-canary.3b5b55e31.0", "safevalues": "^0.3.4", "tslib": "^2.1.0" } }, "node_modules/@material/top-app-bar": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/top-app-bar/-/top-app-bar-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-1M+oupUxflfW7u81P1XlxoLZB8bLzwtpKofIfDNRbEsiKhlLTERJR3Yak3BGE9xakNMysAaBHlkb5MrN5bNPFw==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/top-app-bar/-/top-app-bar-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-N8kJQtkZheUpDgtlr0GudAv5OnGiVhuWlk3IGgDAX06O1vvuV2negj7Il0NJ9YsKJ8t5ICKjlxsznskIbMSxmQ==", "dependencies": { - "@material/animation": "15.0.0-canary.684e33d25.0", - "@material/base": "15.0.0-canary.684e33d25.0", - "@material/elevation": "15.0.0-canary.684e33d25.0", - "@material/ripple": "15.0.0-canary.684e33d25.0", - "@material/rtl": "15.0.0-canary.684e33d25.0", - "@material/shape": "15.0.0-canary.684e33d25.0", - "@material/theme": "15.0.0-canary.684e33d25.0", - "@material/typography": "15.0.0-canary.684e33d25.0", + "@material/animation": "15.0.0-canary.3b5b55e31.0", + "@material/base": "15.0.0-canary.3b5b55e31.0", + "@material/elevation": "15.0.0-canary.3b5b55e31.0", + "@material/ripple": "15.0.0-canary.3b5b55e31.0", + "@material/rtl": "15.0.0-canary.3b5b55e31.0", + "@material/shape": "15.0.0-canary.3b5b55e31.0", + "@material/theme": "15.0.0-canary.3b5b55e31.0", + "@material/typography": "15.0.0-canary.3b5b55e31.0", "tslib": "^2.1.0" } }, "node_modules/@material/touch-target": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/touch-target/-/touch-target-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-zdE69Slg8+T7sTn1OwqZ6H7WBYac9mxJ/JlJqfTqthzIjZRcCxBSYymQJcDHjsrPnUojOtr9U4Tpm5YZ96TEkQ==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/touch-target/-/touch-target-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-fY9ikQKjIXLzMyAqo2Vuc8cGzEYri5jPIYXckjWjkArXTfzqyv8Va0Du10bHBLzqmbLBANre959IRRWULvLPIg==", "dependencies": { - "@material/base": "15.0.0-canary.684e33d25.0", - "@material/feature-targeting": "15.0.0-canary.684e33d25.0", - "@material/rtl": "15.0.0-canary.684e33d25.0", - "@material/theme": "15.0.0-canary.684e33d25.0", + "@material/base": "15.0.0-canary.3b5b55e31.0", + "@material/feature-targeting": "15.0.0-canary.3b5b55e31.0", + "@material/rtl": "15.0.0-canary.3b5b55e31.0", + "@material/theme": "15.0.0-canary.3b5b55e31.0", "tslib": "^2.1.0" } }, "node_modules/@material/typography": { - "version": "15.0.0-canary.684e33d25.0", - "resolved": "https://registry.npmjs.org/@material/typography/-/typography-15.0.0-canary.684e33d25.0.tgz", - "integrity": "sha512-aVnvgMwcfNa/K4wujzpKDIxjGl2hbkEL+m+OKDSQqWYjKcP9QrbzCXJruJBqxrBoPRHLbqo47k5f9uT8raSgjw==", + "version": "15.0.0-canary.3b5b55e31.0", + "resolved": "https://registry.npmjs.org/@material/typography/-/typography-15.0.0-canary.3b5b55e31.0.tgz", + "integrity": "sha512-F52n/Mirtkj7kYOxwkP3rMs8WFsMo2qFuA+dFgcyMxvsqPoNU9oZ3AqR+0Lo3VKai3BSVrdukDm+JhvkHB/Smw==", "dependencies": { - "@material/feature-targeting": "15.0.0-canary.684e33d25.0", - "@material/theme": "15.0.0-canary.684e33d25.0", + "@material/feature-targeting": "15.0.0-canary.3b5b55e31.0", + "@material/theme": "15.0.0-canary.3b5b55e31.0", "tslib": "^2.1.0" } }, "node_modules/@ngtools/webpack": { - "version": "15.2.5", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-15.2.5.tgz", - "integrity": "sha512-wD6GY4xghVK+SQL0dy/M3saGx5pqi7+1VHEr+BBI7IUNYGSqPNzylKNxLBgQiTzfkzvbrZ6MhfaMNkhvSCYr5w==", + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-16.0.1.tgz", + "integrity": "sha512-CZHFPMiJuOe241kO1VSSPOQ5Z9hWWkY7eSs3hnS50Ntgd4YzlHAydqexmEFpXD2YLOFjdbNETCyJ2BQTM4Kwtw==", "dev": true, "engines": { - "node": "^14.20.0 || ^16.13.0 || >=18.10.0", + "node": "^16.14.0 || >=18.10.0", "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", "yarn": ">= 1.13.0" }, "peerDependencies": { - "@angular/compiler-cli": "^15.0.0", - "typescript": ">=4.8.2 <5.0", + "@angular/compiler-cli": "^16.0.0", + "typescript": ">=4.9.3 <5.1", "webpack": "^5.54.0" } }, @@ -4227,9 +4194,9 @@ } }, "node_modules/@npmcli/git/node_modules/which": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-3.0.0.tgz", - "integrity": "sha512-nla//68K9NU6yRiwDY/Q8aU6siKlSs64aEC7+IV56QoAuyQT2ovsJcgGYGyqMOmI/CGN1BOR6mM5EN0FBO+zyQ==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-3.0.1.tgz", + "integrity": "sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==", "dev": true, "dependencies": { "isexe": "^2.0.0" @@ -4305,9 +4272,9 @@ } }, "node_modules/@npmcli/promise-spawn/node_modules/which": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-3.0.0.tgz", - "integrity": "sha512-nla//68K9NU6yRiwDY/Q8aU6siKlSs64aEC7+IV56QoAuyQT2ovsJcgGYGyqMOmI/CGN1BOR6mM5EN0FBO+zyQ==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-3.0.1.tgz", + "integrity": "sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==", "dev": true, "dependencies": { "isexe": "^2.0.0" @@ -4320,9 +4287,9 @@ } }, "node_modules/@npmcli/run-script": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-6.0.0.tgz", - "integrity": "sha512-ql+AbRur1TeOdl1FY+RAwGW9fcr4ZwiVKabdvm93mujGREVuVLbdkXRJDrkTXSdCjaxYydr1wlA2v67jxWG5BQ==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-6.0.2.tgz", + "integrity": "sha512-NCcr1uQo1k5U+SYlnIrbAh3cxy+OQT1VtqiAbxdymSlptbzBb62AjH2xXgjNCoP073hoa1CfCAcwoZ8k96C4nA==", "dev": true, "dependencies": { "@npmcli/node-gyp": "^3.0.0", @@ -4336,9 +4303,9 @@ } }, "node_modules/@npmcli/run-script/node_modules/which": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-3.0.0.tgz", - "integrity": "sha512-nla//68K9NU6yRiwDY/Q8aU6siKlSs64aEC7+IV56QoAuyQT2ovsJcgGYGyqMOmI/CGN1BOR6mM5EN0FBO+zyQ==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-3.0.1.tgz", + "integrity": "sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==", "dev": true, "dependencies": { "isexe": "^2.0.0" @@ -4350,6 +4317,249 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, + "node_modules/@nrwl/devkit": { + "version": "16.0.2", + "resolved": "https://registry.npmjs.org/@nrwl/devkit/-/devkit-16.0.2.tgz", + "integrity": "sha512-SAEcImeQHdSTauO05FUn2vVl9/y5Kx1LNCZ4YE+SdY5/QRq18fuo/DCWmjOGG9M8r06vYGsAgMzkiB4soimcyA==", + "dev": true, + "dependencies": { + "@nx/devkit": "16.0.2" + } + }, + "node_modules/@nrwl/tao": { + "version": "16.0.2", + "resolved": "https://registry.npmjs.org/@nrwl/tao/-/tao-16.0.2.tgz", + "integrity": "sha512-wimEe4OTpI7/nDK67RnpZpEXCU+fzA0sDgpIhMgbpPd0vPmKgaZv4nbs8zrm0goFlacmmnLaGRhhGYMOxE+1Lg==", + "dev": true, + "dependencies": { + "nx": "16.0.2" + }, + "bin": { + "tao": "index.js" + } + }, + "node_modules/@nx/devkit": { + "version": "16.0.2", + "resolved": "https://registry.npmjs.org/@nx/devkit/-/devkit-16.0.2.tgz", + "integrity": "sha512-BY1Bj0BbAl6XJL0O+QGTWPs/3WMJTEQ+Y4Lfoq4dZM7RllE6rAylr54NA2wa4lsgordZhq1+0g5PVhKKvSVRRw==", + "dev": true, + "dependencies": { + "@nrwl/devkit": "16.0.2", + "ejs": "^3.1.7", + "ignore": "^5.0.4", + "semver": "7.3.4", + "tmp": "~0.2.1", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "nx": ">= 15 <= 17" + } + }, + "node_modules/@nx/devkit/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@nx/devkit/node_modules/semver": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@nx/devkit/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/@nx/nx-darwin-arm64": { + "version": "16.0.2", + "resolved": "https://registry.npmjs.org/@nx/nx-darwin-arm64/-/nx-darwin-arm64-16.0.2.tgz", + "integrity": "sha512-nAT8WJ/qKGEvUcoFLHHye1dbwCd7b8CTZJlDF+ZkyCD/UZRHt4eJxy8gvKmxgkZTFb2+PPMQt4UORCUGpZzuoA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-darwin-x64": { + "version": "16.0.2", + "resolved": "https://registry.npmjs.org/@nx/nx-darwin-x64/-/nx-darwin-x64-16.0.2.tgz", + "integrity": "sha512-r0rfOrZaOyrwFR5a0UT05xkYRumfkP65cRSZM1TjCA027AG9llYtkLT1hlz8uMKt+P12zrWVzXSqGLDi022ZZg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-linux-arm-gnueabihf": { + "version": "16.0.2", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-16.0.2.tgz", + "integrity": "sha512-TfDQaGvCIDjn9sPg5U1Fr2rsSul/4PIQB59qrLBJRPiCWgpzwO71Il1qwSX68En+JH3lwXr+g5EjcDIEQ8fGYA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-linux-arm64-gnu": { + "version": "16.0.2", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-16.0.2.tgz", + "integrity": "sha512-MICaUp7uz8WVQFXWPrmQaX1o4bdL7f3C7b3MDDf6+Zau6RcyQuw97UEKaYi9OqrV3w8yuPplqoLosFblAgb8uw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-linux-arm64-musl": { + "version": "16.0.2", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-16.0.2.tgz", + "integrity": "sha512-wcBURG+6A2srm+6ujj8SShjwmYWs0eHI5D8vgZr8Bni+lXbKP/IosE9JGXKtRoh27/owyR8PGHhDVzjv46tlFg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-linux-x64-gnu": { + "version": "16.0.2", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-16.0.2.tgz", + "integrity": "sha512-Xyml2gFdVDHUj2g67DKz2aD78x1BciN1ZaaBTCxXL4MHfwR78SZa7mtRtE+1kj5OgVIwupZP50jq7C8GuSn3Hw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-linux-x64-musl": { + "version": "16.0.2", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-16.0.2.tgz", + "integrity": "sha512-j3xdN8I5DlTgW5N5eCquyBZswrrYf6EazUCvnEpeejygwh3N6XN7DlD68Bs0CB4Zmd0tWLfTjNVAtUJSP6g2mA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-win32-arm64-msvc": { + "version": "16.0.2", + "resolved": "https://registry.npmjs.org/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-16.0.2.tgz", + "integrity": "sha512-R2pzoW3SUFBbe9C1vifJnXuysPl6kmutQHN2yQ9lwJptzPvMxfDU1FuXmKCGRUGmEwFxk/XPhwDL/ZcbABTrzw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-win32-x64-msvc": { + "version": "16.0.2", + "resolved": "https://registry.npmjs.org/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-16.0.2.tgz", + "integrity": "sha512-r4H/SsqfpIJa8QLSpnscgkMnLsnkRYXj8TcILDrf+nJazfEdJZLUvVhN9O85OB7pskv86NuGfnJmJHHXy6QVQg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@parcel/watcher": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.0.4.tgz", + "integrity": "sha512-cTDi+FUDBIUOBKEtj+nhiJ71AZVlkAsQFuGQTun5tV9mwQBQgZvhCzG+URPQc8myeN32yRVZEfVAPCs1RW+Jvg==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "node-addon-api": "^3.2.1", + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, "node_modules/@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", @@ -4405,17 +4615,17 @@ "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" }, "node_modules/@schematics/angular": { - "version": "15.2.5", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-15.2.5.tgz", - "integrity": "sha512-YN0A5bzuqEmLdwbcQRop9TFj0QVxTC/XCL0K5DfDymVBS2j09NMyLLVc6TDOs+J/fMQr5EwiT149ikzqiUmAcw==", + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-16.0.1.tgz", + "integrity": "sha512-MNgH/iB3WWxMLFVHJjtXCHZ8YHtfx2e3mX2Ds5P43OTgSnTk6tHabqvwxJ4wzjoyoPUyXWLhHt0diCmVtDTNeQ==", "dev": true, "dependencies": { - "@angular-devkit/core": "15.2.5", - "@angular-devkit/schematics": "15.2.5", + "@angular-devkit/core": "16.0.1", + "@angular-devkit/schematics": "16.0.1", "jsonc-parser": "3.2.0" }, "engines": { - "node": "^14.20.0 || ^16.13.0 || >=18.10.0", + "node": "^16.14.0 || >=18.10.0", "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", "yarn": ">= 1.13.0" } @@ -4444,6 +4654,34 @@ "node": ">= 10" } }, + "node_modules/@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true, + "peer": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true, + "peer": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true, + "peer": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true, + "peer": true + }, "node_modules/@tufjs/canonical-json": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-1.0.0.tgz", @@ -4454,13 +4692,13 @@ } }, "node_modules/@tufjs/models": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-1.0.2.tgz", - "integrity": "sha512-uxarDtxTIK3f8hJS4yFhW/lvTa3tsiQU5iDCRut+NCnOXvNtEul0Ct58NIIcIx9Rkt7OFEK31Ndpqsd663nsew==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-1.0.4.tgz", + "integrity": "sha512-qaGV9ltJP0EO25YfFUPhxRVK0evXFIAGicsVXuRim4Ed9cjPxYhNnNJ49SFmbeLgtxpslIkX317IgpfcHPVj/A==", "dev": true, "dependencies": { "@tufjs/canonical-json": "1.0.0", - "minimatch": "^8.0.3" + "minimatch": "^9.0.0" }, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" @@ -4476,9 +4714,9 @@ } }, "node_modules/@tufjs/models/node_modules/minimatch": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz", - "integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.0.tgz", + "integrity": "sha512-0jJj8AvgKqWN05mrwuqi8QYKx1WmYSUoKSxu5Qhs9prezTz10sxAHGNZe9J9cqIJzta8DWsleh2KaVaLl6Ru2w==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -4527,9 +4765,9 @@ } }, "node_modules/@types/connect-history-api-fallback": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz", - "integrity": "sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.0.tgz", + "integrity": "sha512-4x5FkPpLipqwthjPsF7ZRbOv3uoLUFkTA9G9v583qi4pACvq0uTELrB8OLUzPWUI4IJIyvM85vzkV1nyiI2Lig==", "dev": true, "dependencies": { "@types/express-serve-static-core": "*", @@ -4572,9 +4810,9 @@ } }, "node_modules/@types/estree": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz", - "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", + "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==" }, "node_modules/@types/express": { "version": "4.17.17", @@ -4589,30 +4827,33 @@ } }, "node_modules/@types/express-serve-static-core": { - "version": "4.17.33", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.33.tgz", - "integrity": "sha512-TPBqmR/HRYI3eC2E5hmiivIzv+bidAfXofM+sbonAGvyDhySGw9/PQZFt2BLOrjUUR++4eJVpx6KnLQK1Fk9tA==", + "version": "4.17.35", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.35.tgz", + "integrity": "sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg==", "dev": true, "dependencies": { "@types/node": "*", "@types/qs": "*", - "@types/range-parser": "*" + "@types/range-parser": "*", + "@types/send": "*" } }, "node_modules/@types/file-saver": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/@types/file-saver/-/file-saver-2.0.5.tgz", - "integrity": "sha512-zv9kNf3keYegP5oThGLaPk8E081DFDuwfqjtiTzm6PoxChdJ1raSuADf2YGCVIyrSynLrgc8JWv296s7Q7pQSQ==" + "integrity": "sha512-zv9kNf3keYegP5oThGLaPk8E081DFDuwfqjtiTzm6PoxChdJ1raSuADf2YGCVIyrSynLrgc8JWv296s7Q7pQSQ==", + "dev": true }, "node_modules/@types/google-protobuf": { "version": "3.15.6", "resolved": "https://registry.npmjs.org/@types/google-protobuf/-/google-protobuf-3.15.6.tgz", - "integrity": "sha512-pYVNNJ+winC4aek+lZp93sIKxnXt5qMkuKmaqS3WGuTq0Bw1ZDYNBgzG5kkdtwcv+GmYJGo3yEg6z2cKKAiEdw==" + "integrity": "sha512-pYVNNJ+winC4aek+lZp93sIKxnXt5qMkuKmaqS3WGuTq0Bw1ZDYNBgzG5kkdtwcv+GmYJGo3yEg6z2cKKAiEdw==", + "dev": true }, "node_modules/@types/http-proxy": { - "version": "1.17.10", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.10.tgz", - "integrity": "sha512-Qs5aULi+zV1bwKAg5z1PWnDXWmsn+LxIvUGv6E2+OOMYhclZMO+OXd9pYVf2gLykf2I7IV2u7oTHwChPNsvJ7g==", + "version": "1.17.11", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.11.tgz", + "integrity": "sha512-HC8G7c1WmaF2ekqpnFq626xd3Zz0uvaqFmBJNRZCGEZCXkvSdJoNFn/8Ygbd9fKNQj8UzLdCETaI0UWPAjK7IA==", "dev": true, "dependencies": { "@types/node": "*" @@ -4640,9 +4881,9 @@ "dev": true }, "node_modules/@types/jsonwebtoken": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.1.tgz", - "integrity": "sha512-c5ltxazpWabia/4UzhIoaDcIza4KViOQhdbjRlfcIGVnsE3c3brkz9Z+F/EeJIECOQP7W7US2hNE930cWWkPiw==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-drE6uz7QBKq1fYqqoFKTDRdFCPHd5TCub75BM+D+cMx7NU9hUz7SESLfC2fSCXVFMO5Yj8sOWHuGqPgjc+fz0Q==", "dev": true, "dependencies": { "@types/node": "*" @@ -4654,21 +4895,15 @@ "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" }, "node_modules/@types/mime": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz", - "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", + "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", "dev": true }, "node_modules/@types/node": { - "version": "18.15.11", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.11.tgz", - "integrity": "sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q==" - }, - "node_modules/@types/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", - "dev": true + "version": "18.16.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.9.tgz", + "integrity": "sha512-IeB32oIV4oGArLrd7znD2rkHQ6EDCM+2Sr76dJnrHwv9OHBTTM6nuDLK9bmikXzPa0ZlWMWtRGo/Uw4mrzQedA==" }, "node_modules/@types/q": { "version": "0.0.32", @@ -4703,17 +4938,27 @@ "dev": true }, "node_modules/@types/selenium-webdriver": { - "version": "3.0.20", - "resolved": "https://registry.npmjs.org/@types/selenium-webdriver/-/selenium-webdriver-3.0.20.tgz", - "integrity": "sha512-6d8Q5fqS9DWOXEhMDiF6/2FjyHdmP/jSTAUyeQR7QwrFeNmYyzmvGxD5aLIHL445HjWgibs0eAig+KPnbaesXA==", + "version": "3.0.21", + "resolved": "https://registry.npmjs.org/@types/selenium-webdriver/-/selenium-webdriver-3.0.21.tgz", + "integrity": "sha512-DRHyGEr25ra2C4+eU7eiCSto2j9eUa9pR4z5uiLRBXWFlmfMCAeXwecZnAhuB3eOOCA8OkwcNlb6QUkVZFlKTA==", "dev": true }, "node_modules/@types/semver": { - "version": "7.3.13", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", - "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz", + "integrity": "sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==", "dev": true }, + "node_modules/@types/send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.1.tgz", + "integrity": "sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==", + "dev": true, + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, "node_modules/@types/serve-index": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz", @@ -4751,9 +4996,10 @@ } }, "node_modules/@types/uuid": { - "version": "8.3.4", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", - "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==" + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-rFT3ak0/2trgvp4yYZo5iKFEPsET7vKydKF+VRCxlQ9bpheehyAJH89dAkaLEq/j/RZXJIqcgsmPJKUP1Z28HA==", + "dev": true }, "node_modules/@types/ws": { "version": "8.5.4", @@ -4765,18 +5011,19 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.48.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.48.2.tgz", - "integrity": "sha512-sR0Gja9Ky1teIq4qJOl0nC+Tk64/uYdX+mi+5iB//MH8gwyx8e3SOyhEzeLZEFEEfCaLf8KJq+Bd/6je1t+CAg==", + "version": "5.59.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.5.tgz", + "integrity": "sha512-feA9xbVRWJZor+AnLNAr7A8JRWeZqHUf4T9tlP+TN04b05pFVhO5eN7/O93Y/1OUlLMHKbnJisgDURs/qvtqdg==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.48.2", - "@typescript-eslint/type-utils": "5.48.2", - "@typescript-eslint/utils": "5.48.2", + "@eslint-community/regexpp": "^4.4.0", + "@typescript-eslint/scope-manager": "5.59.5", + "@typescript-eslint/type-utils": "5.59.5", + "@typescript-eslint/utils": "5.59.5", "debug": "^4.3.4", + "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "natural-compare-lite": "^1.4.0", - "regexpp": "^3.2.0", "semver": "^7.3.7", "tsutils": "^3.21.0" }, @@ -4797,58 +5044,14 @@ } } }, - "node_modules/@typescript-eslint/parser": { - "version": "5.48.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.48.2.tgz", - "integrity": "sha512-38zMsKsG2sIuM5Oi/olurGwYJXzmtdsHhn5mI/pQogP+BjYVkK5iRazCQ8RGS0V+YLk282uWElN70zAAUmaYHw==", + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/type-utils": { + "version": "5.59.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.5.tgz", + "integrity": "sha512-4eyhS7oGym67/pSxA2mmNq7X164oqDYNnZCUayBwJZIRVvKpBCMBzFnFxjeoDeShjtO6RQBHBuwybuX3POnDqg==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.48.2", - "@typescript-eslint/types": "5.48.2", - "@typescript-eslint/typescript-estree": "5.48.2", - "debug": "^4.3.4" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "5.48.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.48.2.tgz", - "integrity": "sha512-zEUFfonQid5KRDKoI3O+uP1GnrFd4tIHlvs+sTJXiWuypUWMuDaottkJuR612wQfOkjYbsaskSIURV9xo4f+Fw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.48.2", - "@typescript-eslint/visitor-keys": "5.48.2" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "5.48.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.48.2.tgz", - "integrity": "sha512-QVWx7J5sPMRiOMJp5dYshPxABRoZV1xbRirqSk8yuIIsu0nvMTZesKErEA3Oix1k+uvsk8Cs8TGJ6kQ0ndAcew==", - "dev": true, - "dependencies": { - "@typescript-eslint/typescript-estree": "5.48.2", - "@typescript-eslint/utils": "5.48.2", + "@typescript-eslint/typescript-estree": "5.59.5", + "@typescript-eslint/utils": "5.59.5", "debug": "^4.3.4", "tsutils": "^3.21.0" }, @@ -4868,10 +5071,186 @@ } } }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": { + "version": "5.59.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.5.tgz", + "integrity": "sha512-sCEHOiw+RbyTii9c3/qN74hYDPNORb8yWCoPLmB7BIflhplJ65u2PBpdRla12e3SSTJ2erRkPjz7ngLHhUegxA==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.59.5", + "@typescript-eslint/types": "5.59.5", + "@typescript-eslint/typescript-estree": "5.59.5", + "eslint-scope": "^5.1.1", + "semver": "^7.3.7" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "5.59.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.5.tgz", + "integrity": "sha512-NJXQC4MRnF9N9yWqQE2/KLRSOLvrrlZb48NGVfBa+RuPMN6B7ZcK5jZOvhuygv4D64fRKnZI4L4p8+M+rfeQuw==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "5.59.5", + "@typescript-eslint/types": "5.59.5", + "@typescript-eslint/typescript-estree": "5.59.5", + "debug": "^4.3.4" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "5.59.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.5.tgz", + "integrity": "sha512-jVecWwnkX6ZgutF+DovbBJirZcAxgxC0EOHYt/niMROf8p4PwxxG32Qdhj/iIQQIuOflLjNkxoXyArkcIP7C3A==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.59.5", + "@typescript-eslint/visitor-keys": "5.59.5" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "5.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.2.tgz", + "integrity": "sha512-b1LS2phBOsEy/T381bxkkywfQXkV1dWda/z0PhnIy3bC5+rQWQDS7fk9CSpcXBccPY27Z6vBEuaPBCKCgYezyQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "5.59.2", + "@typescript-eslint/utils": "5.59.2", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { + "version": "5.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.2.tgz", + "integrity": "sha512-LbJ/HqoVs2XTGq5shkiKaNTuVv5tTejdHgfdjqRUGdYhjW1crm/M7og2jhVskMt8/4wS3T1+PfFvL1K3wqYj4w==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "5.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.2.tgz", + "integrity": "sha512-+j4SmbwVmZsQ9jEyBMgpuBD0rKwi9RxRpjX71Brr73RsYnEr3Lt5QZ624Bxphp8HUkSKfqGnPJp1kA5nl0Sh7Q==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.59.2", + "@typescript-eslint/visitor-keys": "5.59.2", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "5.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.2.tgz", + "integrity": "sha512-EEpsO8m3RASrKAHI9jpavNv9NlEUebV4qmF1OWxSTtKSFBpC1NCmWazDQHFivRf0O1DV11BA645yrLEVQ0/Lig==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.59.2", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/types": { - "version": "5.48.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.48.2.tgz", - "integrity": "sha512-hE7dA77xxu7ByBc6KCzikgfRyBCTst6dZQpwaTy25iMYOnbNljDT4hjhrGEJJ0QoMjrfqrx+j1l1B9/LtKeuqA==", + "version": "5.59.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.5.tgz", + "integrity": "sha512-xkfRPHbqSH4Ggx4eHRIO/eGL8XL4Ysb4woL8c87YuAo8Md7AUjyWKa9YMwTL519SyDPrfEgKdewjkxNCVeJW7w==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -4882,13 +5261,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.48.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.48.2.tgz", - "integrity": "sha512-bibvD3z6ilnoVxUBFEgkO0k0aFvUc4Cttt0dAreEr+nrAHhWzkO83PEVVuieK3DqcgL6VAK5dkzK8XUVja5Zcg==", + "version": "5.59.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.5.tgz", + "integrity": "sha512-+XXdLN2CZLZcD/mO7mQtJMvCkzRfmODbeSKuMY/yXbGkzvA9rJyDY5qDYNoiz2kP/dmyAxXquL2BvLQLJFPQIg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.48.2", - "@typescript-eslint/visitor-keys": "5.48.2", + "@typescript-eslint/types": "5.59.5", + "@typescript-eslint/visitor-keys": "5.59.5", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -4909,18 +5288,18 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "5.48.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.48.2.tgz", - "integrity": "sha512-2h18c0d7jgkw6tdKTlNaM7wyopbLRBiit8oAxoP89YnuBOzCZ8g8aBCaCqq7h208qUTroL7Whgzam7UY3HVLow==", + "version": "5.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.2.tgz", + "integrity": "sha512-kSuF6/77TZzyGPhGO4uVp+f0SBoYxCDf+lW3GKhtKru/L8k/Hd7NFQxyWUeY7Z/KGB2C6Fe3yf2vVi4V9TsCSQ==", "dev": true, "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.48.2", - "@typescript-eslint/types": "5.48.2", - "@typescript-eslint/typescript-estree": "5.48.2", + "@typescript-eslint/scope-manager": "5.59.2", + "@typescript-eslint/types": "5.59.2", + "@typescript-eslint/typescript-estree": "5.59.2", "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0", "semver": "^7.3.7" }, "engines": { @@ -4934,6 +5313,80 @@ "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { + "version": "5.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.2.tgz", + "integrity": "sha512-dB1v7ROySwQWKqQ8rEWcdbTsFjh2G0vn8KUyvTXdPoyzSL6lLGkiXEV5CvpJsEe9xIdKV+8Zqb7wif2issoOFA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.59.2", + "@typescript-eslint/visitor-keys": "5.59.2" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { + "version": "5.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.2.tgz", + "integrity": "sha512-LbJ/HqoVs2XTGq5shkiKaNTuVv5tTejdHgfdjqRUGdYhjW1crm/M7og2jhVskMt8/4wS3T1+PfFvL1K3wqYj4w==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "5.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.2.tgz", + "integrity": "sha512-+j4SmbwVmZsQ9jEyBMgpuBD0rKwi9RxRpjX71Brr73RsYnEr3Lt5QZ624Bxphp8HUkSKfqGnPJp1kA5nl0Sh7Q==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.59.2", + "@typescript-eslint/visitor-keys": "5.59.2", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "5.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.2.tgz", + "integrity": "sha512-EEpsO8m3RASrKAHI9jpavNv9NlEUebV4qmF1OWxSTtKSFBpC1NCmWazDQHFivRf0O1DV11BA645yrLEVQ0/Lig==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.59.2", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/utils/node_modules/eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", @@ -4957,12 +5410,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.48.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.48.2.tgz", - "integrity": "sha512-z9njZLSkwmjFWUelGEwEbdf4NwKvfHxvGC0OcGN1Hp/XNDIcJ7D5DpPNPv6x6/mFvc1tQHsaWmpD/a4gOvvCJQ==", + "version": "5.59.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.5.tgz", + "integrity": "sha512-qL+Oz+dbeBRTeyJTIy0eniD3uvqU7x+y1QceBismZ41hd4aBSRh8UAw4pZP0+XzLuPZmx4raNMq/I+59W2lXKA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.48.2", + "@typescript-eslint/types": "5.59.5", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -4973,149 +5426,161 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@vitejs/plugin-basic-ssl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-1.0.1.tgz", + "integrity": "sha512-pcub+YbFtFhaGRTo1832FQHQSHvMrlb43974e2eS8EKleR3p1cDdkJFPci1UhwkEf1J9Bz+wKBSzqpKp7nNj2A==", + "dev": true, + "engines": { + "node": ">=14.6.0" + }, + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0" + } + }, "node_modules/@webassemblyjs/ast": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", - "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", + "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", "dev": true, "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1" + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" } }, "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", - "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", "dev": true }, "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", - "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", "dev": true }, "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", - "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", + "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==", "dev": true }, "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", - "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", "dev": true, "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", - "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", "dev": true }, "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", - "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", + "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1" + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6" } }, "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", - "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", "dev": true, "dependencies": { "@xtuc/ieee754": "^1.2.0" } }, "node_modules/@webassemblyjs/leb128": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", - "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", "dev": true, "dependencies": { "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/utf8": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", - "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", "dev": true }, "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", - "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", + "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/helper-wasm-section": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-opt": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "@webassemblyjs/wast-printer": "1.11.1" + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-opt": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6", + "@webassemblyjs/wast-printer": "1.11.6" } }, "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", - "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", + "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" } }, "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", - "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", + "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1" + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6" } }, "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", - "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", + "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" } }, "node_modules/@webassemblyjs/wast-printer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", - "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", + "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/ast": "1.11.6", "@xtuc/long": "4.2.2" } }, @@ -5137,6 +5602,37 @@ "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", "dev": true }, + "node_modules/@yarnpkg/parsers": { + "version": "3.0.0-rc.43", + "resolved": "https://registry.npmjs.org/@yarnpkg/parsers/-/parsers-3.0.0-rc.43.tgz", + "integrity": "sha512-AhFF3mIDfA+jEwQv2WMHmiYhOvmdbh2qhUkDVQfiqzQtUwS4BgoWwom5NpSPg4Ix5vOul+w1690Bt21CkVLpgg==", + "dev": true, + "dependencies": { + "js-yaml": "^3.10.0", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=14.15.0" + } + }, + "node_modules/@zkochan/js-yaml": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@zkochan/js-yaml/-/js-yaml-0.0.6.tgz", + "integrity": "sha512-nzvgl3VfhcELQ8LyVrYOru+UtAy1nrygk2+AGbTm8a5YcO6o8lSjAT+pfg3vJWxIoZKOUhrK6UU7xW/+00kQrg==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@zkochan/js-yaml/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, "node_modules/abab": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", @@ -5175,9 +5671,9 @@ } }, "node_modules/acorn-import-assertions": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", - "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", + "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", "dev": true, "peerDependencies": { "acorn": "^8" @@ -5192,6 +5688,16 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/adjust-sourcemap-loader": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz", @@ -5325,16 +5831,16 @@ } }, "node_modules/angularx-qrcode": { - "version": "15.0.1", - "resolved": "https://registry.npmjs.org/angularx-qrcode/-/angularx-qrcode-15.0.1.tgz", - "integrity": "sha512-CirpL2rhhYX/QZ1OSaJ/fusABjDlwl1oYBqaLRqmyie0xTbscWqTBW0DEoht2yCNGN8Wt+JmZwTLxYG6tLuWeQ==", + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/angularx-qrcode/-/angularx-qrcode-16.0.0.tgz", + "integrity": "sha512-j6IndIU3m4zfqSPKraJPFgigdHa+pM3kapRPBnKSwgKNSpljPQu3XNiRUCmQmfGfnh39ShDVca/k091WTjngAA==", "dependencies": { "@types/qrcode": "1.5.0", "qrcode": "1.5.1", "tslib": "^2.3.0" }, "peerDependencies": { - "@angular/core": "^15.0.0" + "@angular/core": "^16.0.0" } }, "node_modules/ansi-colors": { @@ -5434,6 +5940,13 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true, + "peer": true + }, "node_modules/argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -5458,6 +5971,19 @@ "deep-equal": "^2.0.5" } }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", + "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "is-array-buffer": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/array-flatten": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", @@ -5515,6 +6041,12 @@ "integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==", "dev": true }, + "node_modules/async": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", + "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==", + "dev": true + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -5522,9 +6054,9 @@ "dev": true }, "node_modules/autoprefixer": { - "version": "10.4.13", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.13.tgz", - "integrity": "sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==", + "version": "10.4.14", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.14.tgz", + "integrity": "sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ==", "dev": true, "funding": [ { @@ -5537,8 +6069,8 @@ } ], "dependencies": { - "browserslist": "^4.21.4", - "caniuse-lite": "^1.0.30001426", + "browserslist": "^4.21.5", + "caniuse-lite": "^1.0.30001464", "fraction.js": "^4.2.0", "normalize-range": "^0.1.2", "picocolors": "^1.0.0", @@ -5581,6 +6113,17 @@ "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==", "dev": true }, + "node_modules/axios": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz", + "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==", + "dev": true, + "dependencies": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/axobject-query": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.1.1.tgz", @@ -5996,16 +6539,16 @@ } }, "node_modules/cacache": { - "version": "17.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-17.0.4.tgz", - "integrity": "sha512-Z/nL3gU+zTUjz5pCA5vVjYM8pmaw2kxM7JEiE0fv3w77Wj+sFbi70CrBruUWH0uNcEdvLDixFpgA2JM4F4DBjA==", + "version": "17.0.6", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-17.0.6.tgz", + "integrity": "sha512-ixcYmEBExFa/+ajIPjcwypxL97CjJyOsH9A/W+4qgEPIpJvKlC+HmVY8nkIck6n3PwUTdgq9c489niJGwl+5Cw==", "dev": true, "dependencies": { "@npmcli/fs": "^3.1.0", "fs-minipass": "^3.0.0", - "glob": "^8.0.1", + "glob": "^10.2.2", "lru-cache": "^7.7.1", - "minipass": "^4.0.0", + "minipass": "^5.0.0", "minipass-collect": "^1.0.2", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", @@ -6019,6 +6562,37 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, + "node_modules/cacache/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/cacache/node_modules/glob": { + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.2.4.tgz", + "integrity": "sha512-fDboBse/sl1oXSLhIp0FcCJgzW9KmhC/q8ULTKC82zc+DL3TL7FNb8qlt5qqXN53MsKEUSIcb+7DLmEygOE5Yw==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.0.3", + "minimatch": "^9.0.0", + "minipass": "^5.0.0 || ^6.0.0", + "path-scurry": "^1.7.0" + }, + "bin": { + "glob": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/cacache/node_modules/lru-cache": { "version": "7.18.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", @@ -6028,6 +6602,21 @@ "node": ">=12" } }, + "node_modules/cacache/node_modules/minimatch": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.0.tgz", + "integrity": "sha512-0jJj8AvgKqWN05mrwuqi8QYKx1WmYSUoKSxu5Qhs9prezTz10sxAHGNZe9J9cqIJzta8DWsleh2KaVaLl6Ru2w==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -6059,9 +6648,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001478", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001478.tgz", - "integrity": "sha512-gMhDyXGItTHipJj2ApIvR+iVB5hd0KP3svMWWXDvZOmjzJJassGLMfxRkQCSYgGd2gtdL/ReeiyvMSFD1Ss6Mw==", + "version": "1.0.30001487", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001487.tgz", + "integrity": "sha512-83564Z3yWGqXsh2vaH/mhXfEM0wX+NlBCm1jYHOb97TrTWJEmPTccZgeLTPBUUb0PNVo+oomb7wkimZBIERClA==", "dev": true, "funding": [ { @@ -6171,9 +6760,9 @@ } }, "node_modules/cli-spinners": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.8.0.tgz", - "integrity": "sha512-/eG5sJcvEIwxcdYM86k5tPwn0MUzkX5YY3eImTGpJOZgVe4SdTMY14vQpcxgBzJ0wXwAYrS8E+c3uHeK4JNyzQ==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.1.tgz", + "integrity": "sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==", "dev": true, "engines": { "node": ">=6" @@ -6192,17 +6781,14 @@ } }, "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "dependencies": { "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", + "strip-ansi": "^6.0.0", "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" } }, "node_modules/clone": { @@ -6328,9 +6914,9 @@ "dev": true }, "node_modules/codemirror": { - "version": "5.65.12", - "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.12.tgz", - "integrity": "sha512-z2jlHBocElRnPYysN2HAuhXbO3DNB0bcSKmNz3hcWR2Js2Dkhc1bEOxG93Z3DeUrnm+qx56XOY5wQmbP5KY0sw==" + "version": "5.65.13", + "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.13.tgz", + "integrity": "sha512-SVWEzKXmbHmTQQWaz03Shrh4nybG0wXx2MEu3FO4ezbPW8IbnZEd5iGHGEffSUaitKYa3i+pHpBsSvw8sPHtzg==" }, "node_modules/color-convert": { "version": "1.9.3", @@ -6357,9 +6943,9 @@ } }, "node_modules/colorette": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", - "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==", + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", "dev": true }, "node_modules/colors": { @@ -6628,9 +7214,9 @@ } }, "node_modules/core-js-compat": { - "version": "3.30.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.30.0.tgz", - "integrity": "sha512-P5A2h/9mRYZFIAP+5Ab8ns6083IyVpSclU74UNvbGVQ8VM7n3n3/g2yF3AkKQ9NXz2O+ioxLbEWKnDtgsFamhg==", + "version": "3.30.2", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.30.2.tgz", + "integrity": "sha512-nriW1nuJjUgvkEjIot1Spwakz52V9YkYHZAQG6A1eCgC8AA1p0zngrQEP9R0+V6hji5XilWKG1Bd0YRppmGimA==", "dev": true, "dependencies": { "browserslist": "^4.21.5" @@ -6659,21 +7245,64 @@ } }, "node_modules/cosmiconfig": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.1.3.tgz", + "integrity": "sha512-/UkO2JKI18b5jVMJUp0lvKFMpa/Gye+ZgZjKD+DGEN9y7NRcf/nK1A0sp67ONmKtnDCNMS44E6jrk0Yc3bDuUw==", "dev": true, "dependencies": { - "@types/parse-json": "^4.0.0", "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" + "path-type": "^4.0.0" }, "engines": { - "node": ">=10" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" } }, + "node_modules/cosmiconfig-typescript-loader": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-4.3.0.tgz", + "integrity": "sha512-NTxV1MFfZDLPiBMjxbHRwSh5LaLcPMwNdCutmnHJCKoVnlvldPWlllonKwrsRJ5pYZBIBGRWWU2tfvzxgeSW5Q==", + "dev": true, + "engines": { + "node": ">=12", + "npm": ">=6" + }, + "peerDependencies": { + "@types/node": "*", + "cosmiconfig": ">=7", + "ts-node": ">=10", + "typescript": ">=3" + } + }, + "node_modules/cosmiconfig/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/cosmiconfig/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true, + "peer": true + }, "node_modules/critters": { "version": "0.0.16", "resolved": "https://registry.npmjs.org/critters/-/critters-0.0.16.tgz", @@ -6922,16 +7551,17 @@ } }, "node_modules/deep-equal": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.0.tgz", - "integrity": "sha512-RdpzE0Hv4lhowpIUKKMJfeH6C1pXdtT1/it80ubgWqwI3qpuxUBpC1S4hnHg+zjnuOoDkzUtUCEEkG+XG5l3Mw==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.1.tgz", + "integrity": "sha512-lKdkdV6EOGoVn65XaOsPdH4rMxTZOnmFyuIkMjM1i5HHCbfjC97dawgTAy0deYNfuqUqW+Q5VrVaQYtUpSd6yQ==", "dev": true, "dependencies": { + "array-buffer-byte-length": "^1.0.0", "call-bind": "^1.0.2", - "es-get-iterator": "^1.1.2", - "get-intrinsic": "^1.1.3", + "es-get-iterator": "^1.1.3", + "get-intrinsic": "^1.2.0", "is-arguments": "^1.1.1", - "is-array-buffer": "^3.0.1", + "is-array-buffer": "^3.0.2", "is-date-object": "^1.0.5", "is-regex": "^1.1.4", "is-shared-array-buffer": "^1.0.2", @@ -6939,7 +7569,7 @@ "object-is": "^1.1.5", "object-keys": "^1.1.1", "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.4.3", + "regexp.prototype.flags": "^1.5.0", "side-channel": "^1.0.4", "which-boxed-primitive": "^1.0.2", "which-collection": "^1.0.1", @@ -7107,15 +7737,6 @@ "node": ">= 0.8" } }, - "node_modules/dependency-graph": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz", - "integrity": "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==", - "dev": true, - "engines": { - "node": ">= 0.6.0" - } - }, "node_modules/destroy": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", @@ -7154,9 +7775,9 @@ } }, "node_modules/dijkstrajs": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.2.tgz", - "integrity": "sha512-QV6PMaHTCNmKSeP6QoXhVTw9snc9VD8MulTT0Bd99Pacp4SS1cjcrYPgBPmibqKVtMJJfqC6XvOXgPMEEPH/fg==" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.3.tgz", + "integrity": "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==" }, "node_modules/dir-glob": { "version": "3.0.1", @@ -7177,9 +7798,9 @@ "dev": true }, "node_modules/dns-packet": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.5.0.tgz", - "integrity": "sha512-USawdAUzRkV6xrqTjiAEp6M9YagZEzWcSUaZTcIFAiyQWW1SoI6KyId8y2+/71wbgHKQAKd+iupLv4YvEwYWvA==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.0.tgz", + "integrity": "sha512-rza3UH1LwdHh9qyPXp8lkwpjSNk/AMD3dPytUoRoqnypDUhY0xvbdmVhWOfxO68frEfV9BU8V12Ez7ZsHGZpCQ==", "dev": true, "dependencies": { "@leichtgewicht/ip-codec": "^2.0.1" @@ -7267,6 +7888,27 @@ "url": "https://github.com/fb55/domutils?sponsor=1" } }, + "node_modules/dotenv": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", + "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", + "dev": true + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, "node_modules/ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -7283,10 +7925,25 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", "dev": true }, + "node_modules/ejs": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz", + "integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==", + "dev": true, + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/electron-to-chromium": { - "version": "1.4.359", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.359.tgz", - "integrity": "sha512-OoVcngKCIuNXtZnsYoqlCvr0Cf3NIPzDIgwUfI9bdTFjXCrr79lI0kwQstLPZ7WhCezLlGksZk/BFAzoXC7GDw==", + "version": "1.4.394", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.394.tgz", + "integrity": "sha512-0IbC2cfr8w5LxTz+nmn2cJTGafsK9iauV2r5A5scfzyovqLrxuLoxOHE5OBobP3oVIggJT+0JfKnw9sm87c8Hw==", "dev": true }, "node_modules/emoji-regex": { @@ -7340,10 +7997,19 @@ "node": ">=0.10.0" } }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, "node_modules/engine.io": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.4.1.tgz", - "integrity": "sha512-JFYQurD/nbsA5BSPmbaOSLa3tSVj8L6o4srSwXXY3NqE+gGUNmmPTbhn8tjzcCtSqhFgIeqef81ngny8JM25hw==", + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.4.2.tgz", + "integrity": "sha512-FKn/3oMiJjrOEOeUub2WCox6JhxBXq/Zn3fZOMCBxKnNYtsdKjxhl7yR3fZhM9PV+rdE75SU5SYMc+2PGzo+Tg==", "dev": true, "dependencies": { "@types/cookie": "^0.4.1", @@ -7371,9 +8037,9 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.12.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz", - "integrity": "sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==", + "version": "5.14.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.14.0.tgz", + "integrity": "sha512-+DCows0XNwLDcUhbFJPdlQEVnT2zXlCv7hPxemTz86/O+B/hCQ+mb7ydkPKiflpVraqLPCAfu7lDy+hBXueojw==", "dev": true, "dependencies": { "graceful-fs": "^4.2.4", @@ -7383,6 +8049,18 @@ "node": ">=10.13.0" } }, + "node_modules/enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.1" + }, + "engines": { + "node": ">=8.6" + } + }, "node_modules/ent": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", @@ -7456,9 +8134,9 @@ } }, "node_modules/es-module-lexer": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", - "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.2.1.tgz", + "integrity": "sha512-9978wrXM50Y4rTMmW5kXIC09ZdXQZqkE4mxhwkd8VbzsGkXGPgV4zWuqQJgCEzYngdo2dYDa0l8xhX4fkSwJSg==", "dev": true }, "node_modules/es6-promise": { @@ -7477,12 +8155,11 @@ } }, "node_modules/esbuild": { - "version": "0.17.8", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.8.tgz", - "integrity": "sha512-g24ybC3fWhZddZK6R3uD2iF/RIPnRpwJAqLov6ouX3hMbY4+tKolP0VMF3zuIYCaXun+yHwS5IPQ91N2BT191g==", + "version": "0.17.18", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.18.tgz", + "integrity": "sha512-z1lix43jBs6UKjcZVKOw2xx69ffE2aG0PygLL5qJ9OS/gy0Ewd1gW/PUQIOIQGXBHWNywSc0floSKoMFF8aK2w==", "dev": true, "hasInstallScript": true, - "optional": true, "bin": { "esbuild": "bin/esbuild" }, @@ -7490,34 +8167,34 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/android-arm": "0.17.8", - "@esbuild/android-arm64": "0.17.8", - "@esbuild/android-x64": "0.17.8", - "@esbuild/darwin-arm64": "0.17.8", - "@esbuild/darwin-x64": "0.17.8", - "@esbuild/freebsd-arm64": "0.17.8", - "@esbuild/freebsd-x64": "0.17.8", - "@esbuild/linux-arm": "0.17.8", - "@esbuild/linux-arm64": "0.17.8", - "@esbuild/linux-ia32": "0.17.8", - "@esbuild/linux-loong64": "0.17.8", - "@esbuild/linux-mips64el": "0.17.8", - "@esbuild/linux-ppc64": "0.17.8", - "@esbuild/linux-riscv64": "0.17.8", - "@esbuild/linux-s390x": "0.17.8", - "@esbuild/linux-x64": "0.17.8", - "@esbuild/netbsd-x64": "0.17.8", - "@esbuild/openbsd-x64": "0.17.8", - "@esbuild/sunos-x64": "0.17.8", - "@esbuild/win32-arm64": "0.17.8", - "@esbuild/win32-ia32": "0.17.8", - "@esbuild/win32-x64": "0.17.8" + "@esbuild/android-arm": "0.17.18", + "@esbuild/android-arm64": "0.17.18", + "@esbuild/android-x64": "0.17.18", + "@esbuild/darwin-arm64": "0.17.18", + "@esbuild/darwin-x64": "0.17.18", + "@esbuild/freebsd-arm64": "0.17.18", + "@esbuild/freebsd-x64": "0.17.18", + "@esbuild/linux-arm": "0.17.18", + "@esbuild/linux-arm64": "0.17.18", + "@esbuild/linux-ia32": "0.17.18", + "@esbuild/linux-loong64": "0.17.18", + "@esbuild/linux-mips64el": "0.17.18", + "@esbuild/linux-ppc64": "0.17.18", + "@esbuild/linux-riscv64": "0.17.18", + "@esbuild/linux-s390x": "0.17.18", + "@esbuild/linux-x64": "0.17.18", + "@esbuild/netbsd-x64": "0.17.18", + "@esbuild/openbsd-x64": "0.17.18", + "@esbuild/sunos-x64": "0.17.18", + "@esbuild/win32-arm64": "0.17.18", + "@esbuild/win32-ia32": "0.17.18", + "@esbuild/win32-x64": "0.17.18" } }, "node_modules/esbuild-wasm": { - "version": "0.17.8", - "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.17.8.tgz", - "integrity": "sha512-zCmpxv95E0FuCmvdw1K836UHnj4EdiQnFfjTby35y3LAjRPtXMj3sbHDRHjbD8Mqg5lTwq3knacr/1qIFU51CQ==", + "version": "0.17.18", + "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.17.18.tgz", + "integrity": "sha512-h4m5zVa+KaDuRFIbH9dokMwovvkIjTQJS7/Ry+0Z1paVuS9aIkso2vdA2GmwH9GSvGX6w71WveJ3PfkoLuWaRw==", "dev": true, "bin": { "esbuild": "bin/esbuild" @@ -7550,15 +8227,15 @@ } }, "node_modules/eslint": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.38.0.tgz", - "integrity": "sha512-pIdsD2jwlUGf/U38Jv97t8lq6HpaU/G9NKbYmpWpZGw3LdTNhZLbJePqxOXGB5+JEKfOPU/XLxYxFh03nr1KTg==", + "version": "8.40.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.40.0.tgz", + "integrity": "sha512-bvR+TsP9EHL3TqNtj9sCNJVAFK3fBN8Q7g5waghxyRsPLIMwL73XSKnZFK0hk/O2ANC+iAoq6PWMQ+IfBAJIiQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.0.2", - "@eslint/js": "8.38.0", + "@eslint/eslintrc": "^2.0.3", + "@eslint/js": "8.40.0", "@humanwhocodes/config-array": "^0.11.8", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -7568,9 +8245,9 @@ "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-visitor-keys": "^3.4.0", - "espree": "^9.5.1", + "eslint-scope": "^7.2.0", + "eslint-visitor-keys": "^3.4.1", + "espree": "^9.5.2", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -7607,9 +8284,9 @@ } }, "node_modules/eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", + "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", "dev": true, "dependencies": { "esrecurse": "^4.3.0", @@ -7617,39 +8294,15 @@ }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^2.0.0" - }, - "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" }, "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=5" - } - }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true, - "engines": { - "node": ">=10" + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint-visitor-keys": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz", - "integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", + "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -7881,14 +8534,14 @@ } }, "node_modules/espree": { - "version": "9.5.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.1.tgz", - "integrity": "sha512-5yxtHSZXRSW5pvv3hAlXM5+/Oswi1AUFqBmbibKb5s6bp3rGIDkyXU6xCoyuuLhijr4SFwPrXRoZjz0AZDN9tg==", + "version": "9.5.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz", + "integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==", "dev": true, "dependencies": { "acorn": "^8.8.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.0" + "eslint-visitor-keys": "^3.4.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -8286,6 +8939,36 @@ "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz", "integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==" }, + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "dev": true, + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -8377,6 +9060,15 @@ "resolved": "https://registry.npmjs.org/flag-icons/-/flag-icons-6.6.6.tgz", "integrity": "sha512-4lHDKxldnQ7q617pf9Dx9nAetT+9zcMpUexbRrc9kjLw9KJgZ83zA5Dky3Vv7ZDzUjAiZ46x/cy5P0HnEnqA2A==" }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "bin": { + "flat": "cli.js" + } + }, "node_modules/flat-cache": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", @@ -8425,6 +9117,34 @@ "is-callable": "^1.1.3" } }, + "node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.2.tgz", + "integrity": "sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -8435,17 +9155,17 @@ } }, "node_modules/form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", "dev": true, "dependencies": { "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", + "combined-stream": "^1.0.8", "mime-types": "^2.1.12" }, "engines": { - "node": ">= 0.12" + "node": ">= 6" } }, "node_modules/forwarded": { @@ -8479,27 +9199,33 @@ "node": ">= 0.6" } }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true + }, "node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.1.tgz", + "integrity": "sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==", "dev": true, "dependencies": { "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" }, "engines": { - "node": ">=6 <7 || >=8" + "node": ">=14.14" } }, "node_modules/fs-minipass": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.1.tgz", - "integrity": "sha512-MhaJDcFRTuLidHrIttu0RDGyyXs/IYHVmlcxfLAEFIWjc1vdLAkdwT7Ace2u7DbitWC0toKMl5eJZRYNVreIMw==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.2.tgz", + "integrity": "sha512-2GAfyfoaCDRrM6jaOS3UsBts8yJ55VioXdWcOL7dK9zdAuKT71+WBA4ifnNYqVjYv+4SsPxjK0JT4yIIn4cA/g==", "dev": true, "dependencies": { - "minipass": "^4.0.0" + "minipass": "^5.0.0" }, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" @@ -8583,13 +9309,14 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", - "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", + "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", "dev": true, "dependencies": { "function-bind": "^1.1.1", "has": "^1.0.3", + "has-proto": "^1.0.1", "has-symbols": "^1.0.3" }, "funding": { @@ -8873,6 +9600,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-symbols": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", @@ -9146,9 +9885,9 @@ } }, "node_modules/i18n-iso-countries": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/i18n-iso-countries/-/i18n-iso-countries-7.5.0.tgz", - "integrity": "sha512-PtfKJNWLVhhU0KBX/8asmywjAcuyQk07mmmMwxFJcddTNBJJ1yvpY2qxVmyxbtVF+9+6eg9phgpv83XPUKU5CA==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/i18n-iso-countries/-/i18n-iso-countries-7.6.0.tgz", + "integrity": "sha512-HPKjOUKS0BkjiY4ayrsuFbu7Ock++pXLs+FAOYl4WfTL5L0ploEH68fiRAP6Zev5g/jvMFt54KcPGJcb942wbg==", "dependencies": { "diacritics": "1.3.0" }, @@ -9209,12 +9948,12 @@ } }, "node_modules/ignore-walk": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-6.0.2.tgz", - "integrity": "sha512-ezmQ1Dg2b3jVZh2Dh+ar6Eu2MqNSTkyb32HU2MAQQQX9tKM3q/UQ/9lf03lQ5hW+fOeoMnwxwkleZ0xcNp0/qg==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-6.0.3.tgz", + "integrity": "sha512-C7FfFoTA+bI10qfeydT8aZbvr91vAEU+2W5BZUlzPec47oNb07SsOfwYrtxuvOYdUApPP/Qlh4DtAO51Ekk2QA==", "dev": true, "dependencies": { - "minimatch": "^7.4.2" + "minimatch": "^9.0.0" }, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" @@ -9230,15 +9969,15 @@ } }, "node_modules/ignore-walk/node_modules/minimatch": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.6.tgz", - "integrity": "sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.0.tgz", + "integrity": "sha512-0jJj8AvgKqWN05mrwuqi8QYKx1WmYSUoKSxu5Qhs9prezTz10sxAHGNZe9J9cqIJzta8DWsleh2KaVaLl6Ru2w==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=10" + "node": ">=16 || 14 >=14.17" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -9335,12 +10074,12 @@ "dev": true }, "node_modules/ini": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ini/-/ini-3.0.1.tgz", - "integrity": "sha512-it4HyVAUTKBc6m8e1iXWvXSTdndF7HbdN713+kvLrymxTaU4AUBWrJ4vEooP+V7fexnVD3LKcBshjGGPefSMUQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.0.0.tgz", + "integrity": "sha512-t0ikzf5qkSFqRl1e6ejKBe+Tk2bsQd8ivEkcisyGXsku2t8NvXZ1Y3RRz5vxrDgOrTBOi13CvGsVoI5wVpd7xg==", "dev": true, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, "node_modules/inquirer": { @@ -10115,6 +10854,112 @@ "node": ">=8" } }, + "node_modules/jackspeak": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.2.0.tgz", + "integrity": "sha512-r5XBrqIJfwRIjRt/Xr5fv9Wh09qyhHfKnYddDlpM+ibRR20qrYActpCAgU6U+d53EOEjzkvxPMVHSlgR7leXrQ==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jake": { + "version": "10.8.6", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.6.tgz", + "integrity": "sha512-G43Ub9IYEFfu72sua6rzooi8V8Gz2lkfk48rW20vEWCGizeaEPlKB1Kh8JIA84yQbiAEfqlPmSpGgCKKxH3rDA==", + "dev": true, + "dependencies": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.4", + "minimatch": "^3.1.2" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jake/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jake/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jake/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jake/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jake/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jake/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/jasmine": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-2.8.0.tgz", @@ -10313,10 +11158,13 @@ "dev": true }, "node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, "optionalDependencies": { "graceful-fs": "^4.1.6" } @@ -10394,9 +11242,9 @@ } }, "node_modules/karma": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.1.tgz", - "integrity": "sha512-Cj57NKOskK7wtFWSlMvZf459iX+kpYIPXmkNUzP2WAFcA7nhr/ALn5R7sw3w+1udFDcpMx/tuB8d5amgm3ijaA==", + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.2.tgz", + "integrity": "sha512-C6SU/53LB31BEgRg+omznBEMY4SjHU3ricV6zBcAe1EeILKkeScr+fZXtaI5WyDbkVowJxxAI6h73NcFPmXolQ==", "dev": true, "dependencies": { "@colors/colors": "1.5.0", @@ -10432,9 +11280,9 @@ } }, "node_modules/karma-chrome-launcher": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.1.1.tgz", - "integrity": "sha512-hsIglcq1vtboGPAN+DGCISCFOxW+ZVnIqhDQcCMqqCp+4dmJ0Qpq5QAjkbA0X2L9Mi6OBkHi2Srrbmm7pUKkzQ==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.2.0.tgz", + "integrity": "sha512-rE9RkUPI7I9mAxByQWkGJFXfFD6lE4gC5nPuZdobf/QdTEJI6EU4yIay/cfU/xV4ZxlM5JiTv7zWYgA64NpS5Q==", "dev": true, "dependencies": { "which": "^1.2.1" @@ -10503,17 +11351,6 @@ "source-map-support": "^0.5.5" } }, - "node_modules/karma/node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, "node_modules/karma/node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -10588,6 +11425,16 @@ "node": ">= 8" } }, + "node_modules/launch-editor": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.6.0.tgz", + "integrity": "sha512-JpDCcQnyAAzZZaZ7vEiSqL690w7dAEyLao+KC96zBplnYbJS7TYNjvM3M7y3dGz+v7aIsJk3hllWuc0kWAjyRQ==", + "dev": true, + "dependencies": { + "picocolors": "^1.0.0", + "shell-quote": "^1.7.3" + } + }, "node_modules/less": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/less/-/less-4.1.3.tgz", @@ -10705,9 +11552,9 @@ } }, "node_modules/libphonenumber-js": { - "version": "1.10.26", - "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.10.26.tgz", - "integrity": "sha512-oB3l4J5gEhMV+ymmlIjWedsbCpsNRqbEZ/E/MpN2QVyinKNra6DcuXywxSk/72M3DZDoH/6kzurOq1erznBMwQ==" + "version": "1.10.30", + "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.10.30.tgz", + "integrity": "sha512-PLGc+xfrQrkya/YK2/5X+bPpxRmyJBHM+xxz9krUdSgk4Vs2ZwxX5/Ow0lv3r9PDlDtNWb4u+it8MY5rZ0IyGw==" }, "node_modules/license-webpack-plugin": { "version": "4.0.2", @@ -10736,10 +11583,13 @@ } }, "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-2.0.3.tgz", + "integrity": "sha512-cNOjgCnLB+FnvWWtyRTzmB3POJ+cXxTA81LoW7u8JdmhfXzriropYwpjShnz1QLLWsQwY7nIxoDmcPTwphDK9w==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } }, "node_modules/loader-runner": { "version": "4.3.0", @@ -10910,9 +11760,9 @@ } }, "node_modules/magic-string": { - "version": "0.29.0", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.29.0.tgz", - "integrity": "sha512-WcfidHrDjMY+eLjlU+8OvwREqHwpgCeKVBUpQ3OhYYuvfaYCUgcbuBzappNzZvg/v8onU3oQj+BYpkOJe9Iw4Q==", + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.0.tgz", + "integrity": "sha512-LA+31JYDJLs82r2ScLrlz1GjSgu66ZV518eyWT+S8VhyQn/JL0u9MeBOvQMGYiPk1DBiSN9DDMOcXvigJZaViQ==", "dev": true, "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.13" @@ -10945,6 +11795,13 @@ "semver": "bin/semver.js" } }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true, + "peer": true + }, "node_modules/make-fetch-happen": { "version": "10.2.1", "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz", @@ -11121,9 +11978,9 @@ } }, "node_modules/memfs": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.0.tgz", - "integrity": "sha512-yK6o8xVJlQerz57kvPROwTMgx5WtGwC2ZxDtOUsnGl49rHjYkfQoPNZPCKH73VdLE1BwBu/+Fx/NL8NYMUw2aA==", + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.1.tgz", + "integrity": "sha512-UWbFJKvj5k+nETdteFndTpYxdeTMox/ULeqX5k/dpaQJCCFmj5EeKv3dBcyO2xmkRAx2vppRu5dVG7SOtsGOzA==", "dev": true, "dependencies": { "fs-monkey": "^1.0.3" @@ -11218,9 +12075,9 @@ } }, "node_modules/mini-css-extract-plugin": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.2.tgz", - "integrity": "sha512-EdlUizq13o0Pd+uCp+WO/JpkLvHRVGt97RqfeGhXqAcorYo1ypJSpkV+WDT0vY/kmh/p7wRdJNJtuyK540PXDw==", + "version": "2.7.5", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.5.tgz", + "integrity": "sha512-9HaR++0mlgom81s95vvNjxkg52n2b5s//3ZTI1EtzFb98awsLSivs2LMsVqnQ3ay0PVhqWcGNyDaTE961FOcjQ==", "dev": true, "dependencies": { "schema-utils": "^4.0.0" @@ -11264,9 +12121,9 @@ } }, "node_modules/minipass": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", - "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", "dev": true, "engines": { "node": ">=8" @@ -11506,6 +12363,15 @@ "node": "*" } }, + "node_modules/mrmime": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.1.tgz", + "integrity": "sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -11650,8 +12516,7 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==", - "dev": true, - "optional": true + "dev": true }, "node_modules/node-forge": { "version": "1.3.1", @@ -11691,7 +12556,6 @@ "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", "integrity": "sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==", "dev": true, - "optional": true, "bin": { "node-gyp-build": "bin.js", "node-gyp-build-optional": "optional.js", @@ -11785,9 +12649,9 @@ } }, "node_modules/npm-install-checks": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-6.1.0.tgz", - "integrity": "sha512-udSGENih/5xKh3Ex+L0PtZcOt0Pa+6ppDLnpG5D49/EhMja3LupaY9E/DtJTxyFBwE09ot7Fc+H4DywnZNWTVA==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-6.1.1.tgz", + "integrity": "sha512-dH3GmQL4vsPtld59cOn8uY0iOqRmqKvV+DLGwNXV/Q7MDgD2QfOADWd/mFXcIE5LVhYYGjA3baz6W9JneqnuCw==", "dev": true, "dependencies": { "semver": "^7.1.1" @@ -11797,9 +12661,9 @@ } }, "node_modules/npm-normalize-package-bin": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.0.tgz", - "integrity": "sha512-g+DPQSkusnk7HYXr75NtzkIP4+N81i3RPsGFidF3DzHd9MT9wWngmqoeg/fnHFz5MNdtG4w03s+QnhewSLTT2Q==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz", + "integrity": "sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==", "dev": true, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" @@ -11848,13 +12712,13 @@ } }, "node_modules/npm-registry-fetch": { - "version": "14.0.3", - "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-14.0.3.tgz", - "integrity": "sha512-YaeRbVNpnWvsGOjX2wk5s85XJ7l1qQBGAp724h8e2CZFFhMSuw9enom7K1mWVUtvXO1uUSFIAPofQK0pPN0ZcA==", + "version": "14.0.5", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-14.0.5.tgz", + "integrity": "sha512-kIDMIo4aBm6xg7jOttupWZamsZRkAqMqwqqbVXnUqstY5+tapvv6bkH/qMR76jdgV+YljEUCyWx3hRYMrJiAgA==", "dev": true, "dependencies": { "make-fetch-happen": "^11.0.0", - "minipass": "^4.0.0", + "minipass": "^5.0.0", "minipass-fetch": "^3.0.0", "minipass-json-stream": "^1.0.1", "minizlib": "^2.1.2", @@ -11875,9 +12739,9 @@ } }, "node_modules/npm-registry-fetch/node_modules/make-fetch-happen": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-11.0.3.tgz", - "integrity": "sha512-oPLh5m10lRNNZDjJ2kP8UpboUx2uFXVaVweVe/lWut4iHWcQEmfqSVJt2ihZsFI8HbpwyyocaXbCAWf0g1ukIA==", + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz", + "integrity": "sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==", "dev": true, "dependencies": { "agentkeepalive": "^4.2.1", @@ -11887,7 +12751,7 @@ "https-proxy-agent": "^5.0.0", "is-lambda": "^1.0.1", "lru-cache": "^7.7.1", - "minipass": "^4.0.0", + "minipass": "^5.0.0", "minipass-fetch": "^3.0.0", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", @@ -11901,12 +12765,12 @@ } }, "node_modules/npm-registry-fetch/node_modules/minipass-fetch": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.1.tgz", - "integrity": "sha512-t9/wowtf7DYkwz8cfMSt0rMwiyNIBXf5CKZ3S5ZMqRqMYT0oLTp0x1WorMI9WTwvaPg21r1JbFxJMum8JrLGfw==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.3.tgz", + "integrity": "sha512-n5ITsTkDqYkYJZjcRWzZt9qnZKCT7nKCosJhHoj7S7zD+BP4jVbWs+odsniw5TA3E0sLomhTKOKjF86wf11PuQ==", "dev": true, "dependencies": { - "minipass": "^4.0.0", + "minipass": "^5.0.0", "minipass-sized": "^1.0.3", "minizlib": "^2.1.2" }, @@ -11956,6 +12820,241 @@ "url": "https://github.com/fb55/nth-check?sponsor=1" } }, + "node_modules/nx": { + "version": "16.0.2", + "resolved": "https://registry.npmjs.org/nx/-/nx-16.0.2.tgz", + "integrity": "sha512-8Z9Bo1D2VbYjyC/F2ONensKjm10snz1UfkzURZiFA+oXikBPldiH1u67TOTpoCYZfyYQg4l6h6EpOaAvHF6Abg==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@nrwl/tao": "16.0.2", + "@parcel/watcher": "2.0.4", + "@yarnpkg/lockfile": "^1.1.0", + "@yarnpkg/parsers": "^3.0.0-rc.18", + "@zkochan/js-yaml": "0.0.6", + "axios": "^1.0.0", + "chalk": "^4.1.0", + "cli-cursor": "3.1.0", + "cli-spinners": "2.6.1", + "cliui": "^7.0.2", + "dotenv": "~10.0.0", + "enquirer": "~2.3.6", + "fast-glob": "3.2.7", + "figures": "3.2.0", + "flat": "^5.0.2", + "fs-extra": "^11.1.0", + "glob": "7.1.4", + "ignore": "^5.0.4", + "js-yaml": "4.1.0", + "jsonc-parser": "3.2.0", + "lines-and-columns": "~2.0.3", + "minimatch": "3.0.5", + "npm-run-path": "^4.0.1", + "open": "^8.4.0", + "semver": "7.3.4", + "string-width": "^4.2.3", + "strong-log-transformer": "^2.1.0", + "tar-stream": "~2.2.0", + "tmp": "~0.2.1", + "tsconfig-paths": "^4.1.2", + "tslib": "^2.3.0", + "v8-compile-cache": "2.3.0", + "yargs": "^17.6.2", + "yargs-parser": "21.1.1" + }, + "bin": { + "nx": "bin/nx.js" + }, + "optionalDependencies": { + "@nx/nx-darwin-arm64": "16.0.2", + "@nx/nx-darwin-x64": "16.0.2", + "@nx/nx-linux-arm-gnueabihf": "16.0.2", + "@nx/nx-linux-arm64-gnu": "16.0.2", + "@nx/nx-linux-arm64-musl": "16.0.2", + "@nx/nx-linux-x64-gnu": "16.0.2", + "@nx/nx-linux-x64-musl": "16.0.2", + "@nx/nx-win32-arm64-msvc": "16.0.2", + "@nx/nx-win32-x64-msvc": "16.0.2" + }, + "peerDependencies": { + "@swc-node/register": "^1.4.2", + "@swc/core": "^1.2.173" + }, + "peerDependenciesMeta": { + "@swc-node/register": { + "optional": true + }, + "@swc/core": { + "optional": true + } + } + }, + "node_modules/nx/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/nx/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/nx/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/nx/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/nx/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/nx/node_modules/fast-glob": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", + "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nx/node_modules/glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/nx/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/nx/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/nx/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/nx/node_modules/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/nx/node_modules/semver": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/nx/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nx/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", @@ -12077,9 +13176,9 @@ } }, "node_modules/open": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.1.tgz", - "integrity": "sha512-/4b7qZNhv6Uhd7jjnREh1NjnPxlTq+XNWPG88Ydkj5AILcA5m3ajvcg57pB24EQjKv0dK62XnDqk9c/hkIG5Kg==", + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", "dev": true, "dependencies": { "define-lazy-prop": "^2.0.0", @@ -12283,9 +13382,9 @@ } }, "node_modules/pacote": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/pacote/-/pacote-15.1.0.tgz", - "integrity": "sha512-FFcjtIl+BQNfeliSm7MZz5cpdohvUV1yjGnqgVM4UnVF7JslRY0ImXAygdaCDV0jjUADEWu4y5xsDV8brtrTLg==", + "version": "15.1.3", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-15.1.3.tgz", + "integrity": "sha512-aRts8cZqxiJVDitmAh+3z+FxuO3tLNWEmwDRPEpDDiZJaRz06clP4XX112ynMT5uF0QNoMPajBBHnaStUEPJXA==", "dev": true, "dependencies": { "@npmcli/git": "^4.0.0", @@ -12294,7 +13393,7 @@ "@npmcli/run-script": "^6.0.0", "cacache": "^17.0.0", "fs-minipass": "^3.0.0", - "minipass": "^4.0.0", + "minipass": "^5.0.0", "npm-package-arg": "^10.0.0", "npm-packlist": "^7.0.0", "npm-pick-manifest": "^8.0.0", @@ -12303,7 +13402,7 @@ "promise-retry": "^2.0.1", "read-package-json": "^6.0.0", "read-package-json-fast": "^3.0.0", - "sigstore": "^1.0.0", + "sigstore": "^1.3.0", "ssri": "^10.0.0", "tar": "^6.1.11" }, @@ -12350,6 +13449,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/parse-json/node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, "node_modules/parse-node-version": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", @@ -12386,9 +13491,9 @@ } }, "node_modules/parse5-html-rewriting-stream/node_modules/entities": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz", - "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "dev": true, "engines": { "node": ">=0.12" @@ -12425,9 +13530,9 @@ } }, "node_modules/parse5/node_modules/entities": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz", - "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "devOptional": true, "engines": { "node": ">=0.12" @@ -12484,13 +13589,13 @@ "dev": true }, "node_modules/path-scurry": { - "version": "1.6.4", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.6.4.tgz", - "integrity": "sha512-Qp/9IHkdNiXJ3/Kon++At2nVpnhRiPq/aSvQN+H3U1WZbvNRK0RIQK/o4HMqPoXjpuGJUEWpHSs6Mnjxqh3TQg==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.9.1.tgz", + "integrity": "sha512-UgmoiySyjFxP6tscZDgWGEAgsW5ok8W3F5CJDnnH2pozwSTGE6eH7vwTotMwATWA2r5xqdkKdxYPkwlJjAI/3g==", "dev": true, "dependencies": { - "lru-cache": "^9.0.0", - "minipass": "^5.0.0" + "lru-cache": "^9.1.1", + "minipass": "^5.0.0 || ^6.0.0" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -12500,23 +13605,14 @@ } }, "node_modules/path-scurry/node_modules/lru-cache": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-9.0.1.tgz", - "integrity": "sha512-C8QsKIN1UIXeOs3iWmiZ1lQY+EnKDojWd37fXy1aSbJvH4iSma1uy2OWuoB3m4SYRli5+CUjDv3Dij5DVoetmg==", + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-9.1.1.tgz", + "integrity": "sha512-65/Jky17UwSb0BuB9V+MyDpsOtXKmYwzhyl+cOa9XUiI4uV2Ouy/2voFP3+al0BjZbJgMBD8FojMpAf+Z+qn4A==", "dev": true, "engines": { "node": "14 || >=16.14" } }, - "node_modules/path-scurry/node_modules/minipass": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", - "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", @@ -12621,9 +13717,9 @@ } }, "node_modules/postcss": { - "version": "8.4.21", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz", - "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==", + "version": "8.4.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.23.tgz", + "integrity": "sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA==", "dev": true, "funding": [ { @@ -12633,10 +13729,14 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "dependencies": { - "nanoid": "^3.3.4", + "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" }, @@ -12645,13 +13745,14 @@ } }, "node_modules/postcss-loader": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-7.0.2.tgz", - "integrity": "sha512-fUJzV/QH7NXUAqV8dWJ9Lg4aTkDCezpTS5HgJ2DvqznexTbSTxgi/dTECvTZ15BwKTtk8G/bqI/QTu2HPd3ZCg==", + "version": "7.2.4", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-7.2.4.tgz", + "integrity": "sha512-F88rpxxNspo5hatIc+orYwZDtHFaVFOSIVAx+fBfJC1GmhWbVmPWtmg2gXKE1OxJbneOSGn8PWdIwsZFcruS+w==", "dev": true, "dependencies": { - "cosmiconfig": "^7.0.0", - "klona": "^2.0.5", + "cosmiconfig": "^8.1.3", + "cosmiconfig-typescript-loader": "^4.3.0", + "klona": "^2.0.6", "semver": "^7.3.8" }, "engines": { @@ -12663,7 +13764,17 @@ }, "peerDependencies": { "postcss": "^7.0.0 || ^8.0.1", + "ts-node": ">=10", + "typescript": ">=4", "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "ts-node": { + "optional": true + }, + "typescript": { + "optional": true + } } }, "node_modules/postcss-modules-extract-imports": { @@ -12726,9 +13837,9 @@ } }, "node_modules/postcss-selector-parser": { - "version": "6.0.11", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz", - "integrity": "sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==", + "version": "6.0.12", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.12.tgz", + "integrity": "sha512-NdxGCAZdRrwVI1sy59+Wzrh+pMMHxapGnpfenDVlMEXoOcvt4pGE0JLK9YY2F5dLxcFYA/YbVQKhcGU+FtSYQg==", "dev": true, "dependencies": { "cssesc": "^3.0.0", @@ -12754,9 +13865,9 @@ } }, "node_modules/prettier": { - "version": "2.8.7", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.7.tgz", - "integrity": "sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw==", + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", "dev": true, "bin": { "prettier": "bin-prettier.js" @@ -12858,9 +13969,9 @@ } }, "node_modules/protobufjs/node_modules/long": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/long/-/long-5.2.1.tgz", - "integrity": "sha512-GKSNGeNAtw8IryjjkhZxuKB3JzlcLTwjtiQCHKvqQet81I93kXslhDQruGI/QsddO83mcDToBVy7GqGS/zYf/A==" + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" }, "node_modules/protractor": { "version": "7.0.0", @@ -13149,6 +14260,12 @@ "node": ">= 0.10" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true + }, "node_modules/prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", @@ -13367,12 +14484,12 @@ } }, "node_modules/read-package-json": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-6.0.1.tgz", - "integrity": "sha512-AaHqXxfAVa+fNL07x8iAghfKOds/XXsu7zoouIVsbm7PEbQ3nMWXlvjcbrNLjElnUHWQtAo4QEa0RXuvD4XlpA==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-6.0.3.tgz", + "integrity": "sha512-4QbpReW4kxFgeBQ0vPAqh2y8sXEB3D4t3jsXbJKIhBiF80KT6XRo45reqwtftju5J6ru1ax06A2Gb/wM1qCOEQ==", "dev": true, "dependencies": { - "glob": "^9.3.0", + "glob": "^10.2.2", "json-parse-even-better-errors": "^3.0.0", "normalize-package-data": "^5.0.0", "npm-normalize-package-bin": "^3.0.0" @@ -13413,15 +14530,19 @@ } }, "node_modules/read-package-json/node_modules/glob": { - "version": "9.3.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz", - "integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==", + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.2.4.tgz", + "integrity": "sha512-fDboBse/sl1oXSLhIp0FcCJgzW9KmhC/q8ULTKC82zc+DL3TL7FNb8qlt5qqXN53MsKEUSIcb+7DLmEygOE5Yw==", "dev": true, "dependencies": { - "fs.realpath": "^1.0.0", - "minimatch": "^8.0.2", - "minipass": "^4.2.4", - "path-scurry": "^1.6.1" + "foreground-child": "^3.1.0", + "jackspeak": "^2.0.3", + "minimatch": "^9.0.0", + "minipass": "^5.0.0 || ^6.0.0", + "path-scurry": "^1.7.0" + }, + "bin": { + "glob": "dist/cjs/src/bin.js" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -13440,9 +14561,9 @@ } }, "node_modules/read-package-json/node_modules/minimatch": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz", - "integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.0.tgz", + "integrity": "sha512-0jJj8AvgKqWN05mrwuqi8QYKx1WmYSUoKSxu5Qhs9prezTz10sxAHGNZe9J9cqIJzta8DWsleh2KaVaLl6Ru2w==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -13526,14 +14647,14 @@ "dev": true }, "node_modules/regexp.prototype.flags": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", - "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz", + "integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "functions-have-names": "^1.2.2" + "define-properties": "^1.2.0", + "functions-have-names": "^1.2.3" }, "engines": { "node": ">= 0.4" @@ -13542,18 +14663,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, "node_modules/regexpu-core": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", @@ -13624,6 +14733,20 @@ "node": ">= 6" } }, + "node_modules/request/node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, "node_modules/request/node_modules/qs": { "version": "6.5.3", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", @@ -13672,12 +14795,12 @@ "dev": true }, "node_modules/resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", + "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", "dev": true, "dependencies": { - "is-core-module": "^2.9.0", + "is-core-module": "^2.11.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -13809,6 +14932,22 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/rollup": { + "version": "3.21.7", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.21.7.tgz", + "integrity": "sha512-KXPaEuR8FfUoK2uHwNjxTmJ18ApyvD6zJpYv9FOJSqLStmt6xOY84l1IjK2dSolQmoXknrhEFRaPRgOPdqCT5w==", + "dev": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=14.18.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, "node_modules/run-async": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", @@ -13842,9 +14981,9 @@ } }, "node_modules/rxjs": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.0.tgz", - "integrity": "sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==", + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", "dependencies": { "tslib": "^2.1.0" } @@ -13881,9 +15020,9 @@ "integrity": "sha512-LRneZZRXNgjzwG4bDQdOTSbze3fHm1EAKN/8bePxnlEZiBmkYEDggaHbuvHI9/hoqHbGfsEA7tWS9GhYHZBBsw==" }, "node_modules/sass": { - "version": "1.58.1", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.58.1.tgz", - "integrity": "sha512-bnINi6nPXbP1XNRaranMFEBZWUfdW/AF16Ql5+ypRxfTvCRTTKrLsMIakyDcayUt2t/RZotmL4kgJwNH5xO+bg==", + "version": "1.62.1", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.62.1.tgz", + "integrity": "sha512-NHpxIzN29MXvWiuswfc1W3I0N8SXBd8UR26WntmDlRYf0bSADnwnOjsyMZ3lMezSlArD33Vs3YFhp7dWvL770A==", "dev": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0", @@ -13894,16 +15033,16 @@ "sass": "sass.js" }, "engines": { - "node": ">=12.0.0" + "node": ">=14.0.0" } }, "node_modules/sass-loader": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-13.2.0.tgz", - "integrity": "sha512-JWEp48djQA4nbZxmgC02/Wh0eroSUutulROUusYJO9P9zltRbNN80JCBHqRGzjd4cmZCa/r88xgfkjGD0TXsHg==", + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-13.2.2.tgz", + "integrity": "sha512-nrIdVAAte3B9icfBiGWvmMhT/D+eCDwnk+yA7VE/76dp/WkHX+i44Q/pfo71NYbwj0Ap+PGsn0ekOuU1WFJ2AA==", "dev": true, "dependencies": { - "klona": "^2.0.4", + "klona": "^2.0.6", "neo-async": "^2.6.2" }, "engines": { @@ -13988,15 +15127,15 @@ "dev": true }, "node_modules/schema-utils": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", - "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.1.tgz", + "integrity": "sha512-lELhBAAly9NowEsX0yZBlw9ahZG+sK/1RJ21EpzdYHKEs13Vku3LJ+MIPhh4sMs0oCCeufZQEQbMekiA4vuVIQ==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.9", - "ajv": "^8.8.0", + "ajv": "^8.9.0", "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.0.0" + "ajv-keywords": "^5.1.0" }, "engines": { "node": ">= 12.13.0" @@ -14084,9 +15223,9 @@ } }, "node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.4.0.tgz", + "integrity": "sha512-RgOxM8Mw+7Zus0+zcLEUn8+JfoLpj/huFTItQy2hsM4khuC1HYRDp0cU482Ewn/Fcy6bCjufD8vAj7voC66KQw==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -14343,6 +15482,15 @@ "node": ">=8" } }, + "node_modules/shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/side-channel": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", @@ -14364,14 +15512,14 @@ "dev": true }, "node_modules/sigstore": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-1.2.0.tgz", - "integrity": "sha512-Fr9+W1nkBSIZCkJQR7jDn/zI0UXNsVpp+7mDQkCnZOIxG9p6yNXBx9xntHsfUyYHE55XDkkVV3+rYbrkzAeesA==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-1.5.0.tgz", + "integrity": "sha512-i3nhvdobiPj8XrXNIggjeur6+A5iAQ4f+r1bR5SGitFJBbthy/6c7Fz0h+kY70Wua1FSMdDr/UEhXSVRXNpynw==", "dev": true, "dependencies": { "@sigstore/protobuf-specs": "^0.1.0", "make-fetch-happen": "^11.0.1", - "tuf-js": "^1.0.0" + "tuf-js": "^1.1.3" }, "bin": { "sigstore": "bin/sigstore.js" @@ -14390,9 +15538,9 @@ } }, "node_modules/sigstore/node_modules/make-fetch-happen": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-11.0.3.tgz", - "integrity": "sha512-oPLh5m10lRNNZDjJ2kP8UpboUx2uFXVaVweVe/lWut4iHWcQEmfqSVJt2ihZsFI8HbpwyyocaXbCAWf0g1ukIA==", + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz", + "integrity": "sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==", "dev": true, "dependencies": { "agentkeepalive": "^4.2.1", @@ -14402,7 +15550,7 @@ "https-proxy-agent": "^5.0.0", "is-lambda": "^1.0.1", "lru-cache": "^7.7.1", - "minipass": "^4.0.0", + "minipass": "^5.0.0", "minipass-fetch": "^3.0.0", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", @@ -14416,12 +15564,12 @@ } }, "node_modules/sigstore/node_modules/minipass-fetch": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.1.tgz", - "integrity": "sha512-t9/wowtf7DYkwz8cfMSt0rMwiyNIBXf5CKZ3S5ZMqRqMYT0oLTp0x1WorMI9WTwvaPg21r1JbFxJMum8JrLGfw==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.3.tgz", + "integrity": "sha512-n5ITsTkDqYkYJZjcRWzZt9qnZKCT7nKCosJhHoj7S7zD+BP4jVbWs+odsniw5TA3E0sLomhTKOKjF86wf11PuQ==", "dev": true, "dependencies": { - "minipass": "^4.0.0", + "minipass": "^5.0.0", "minipass-sized": "^1.0.3", "minizlib": "^2.1.2" }, @@ -14702,12 +15850,12 @@ } }, "node_modules/ssri": { - "version": "10.0.3", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.3.tgz", - "integrity": "sha512-lJtX/BFPI/VEtxZmLfeh7pzisIs6micwZ3eruD3+ds9aPsXKlYpwDS2Q7omD6WC42WO9+bnUSzlMmfv8uK8meg==", + "version": "10.0.4", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.4.tgz", + "integrity": "sha512-12+IR2CB2C28MMAw0Ncqwj5QbTcs0nGIhgJzYWzDkb21vWmfNI83KS4f3Ci6GI98WreIfG7o9UXp3C0qbpA8nQ==", "dev": true, "dependencies": { - "minipass": "^4.0.0" + "minipass": "^5.0.0" }, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" @@ -14748,6 +15896,38 @@ "node": ">=8.0" } }, + "node_modules/streamroller/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/streamroller/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/streamroller/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -14770,6 +15950,21 @@ "node": ">=8" } }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -14781,6 +15976,28 @@ "node": ">=8" } }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", @@ -14802,6 +16019,23 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/strong-log-transformer": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/strong-log-transformer/-/strong-log-transformer-2.1.0.tgz", + "integrity": "sha512-B3Hgul+z0L9a236FAUC9iZsL+nVHgoCJnqCbN588DjYxvGXaXaaFbfmQ/JhvKjZwsOukuR72XbHv71Qkug0HxA==", + "dev": true, + "dependencies": { + "duplexer": "^0.1.1", + "minimist": "^1.2.0", + "through": "^2.3.4" + }, + "bin": { + "sl-log-transformer": "bin/sl-log-transformer.js" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -14845,14 +16079,14 @@ } }, "node_modules/tar": { - "version": "6.1.13", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.13.tgz", - "integrity": "sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw==", + "version": "6.1.14", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.14.tgz", + "integrity": "sha512-piERznXu0U7/pW7cdSn7hjqySIVTYT6F76icmFk7ptU7dDYlXTm5r9A6K04R2vU3olYgoKeo1Cg3eeu5nhftAw==", "dev": true, "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", - "minipass": "^4.0.0", + "minipass": "^5.0.0", "minizlib": "^2.1.1", "mkdirp": "^1.0.3", "yallist": "^4.0.0" @@ -14861,6 +16095,22 @@ "node": ">=10" } }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/tar/node_modules/fs-minipass": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", @@ -14904,9 +16154,9 @@ "dev": true }, "node_modules/terser": { - "version": "5.16.3", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.16.3.tgz", - "integrity": "sha512-v8wWLaS/xt3nE9dgKEWhNUFP6q4kngO5B8eYFUuebsu7Dw/UNAnpUod6UHo04jSSkv8TzKHjZDSd7EXdDQAl8Q==", + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.17.1.tgz", + "integrity": "sha512-hVl35zClmpisy6oaoKALOpS0rDYLxRFLHhRuDlEGTKey9qHjS1w9GMORjuwIMt70Wan4lwsLYyWDVnWgF+KUEw==", "dev": true, "dependencies": { "@jridgewell/source-map": "^0.3.2", @@ -14922,16 +16172,16 @@ } }, "node_modules/terser-webpack-plugin": { - "version": "5.3.7", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.7.tgz", - "integrity": "sha512-AfKwIktyP7Cu50xNjXF/6Qb5lBNzYaWpU6YfoX3uZicTx0zTy0stDDCsvjDapKsSDvOeWo5MEq4TmdBy2cNoHw==", + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.8.tgz", + "integrity": "sha512-WiHL3ElchZMsK27P8uIUh4604IgJyAW47LVXGbEoB21DbQcZ+OuMpGjVYnEUaqcWM6dO8uS2qUbA7LSCWqvsbg==", "dev": true, "dependencies": { "@jridgewell/trace-mapping": "^0.3.17", "jest-worker": "^27.4.5", "schema-utils": "^3.1.1", "serialize-javascript": "^6.0.1", - "terser": "^5.16.5" + "terser": "^5.16.8" }, "engines": { "node": ">= 10.13.0" @@ -14987,9 +16237,9 @@ "dev": true }, "node_modules/terser-webpack-plugin/node_modules/schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.2.tgz", + "integrity": "sha512-pvjEHOgWc9OWA/f/DE3ohBWTD6EleVLf7iFUkoSwAxttdBhB9QUebQgxER2kWueOvRJXPHNnyrvvh9eZINB8Eg==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.8", @@ -15004,24 +16254,6 @@ "url": "https://opencollective.com/webpack" } }, - "node_modules/terser-webpack-plugin/node_modules/terser": { - "version": "5.16.9", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.16.9.tgz", - "integrity": "sha512-HPa/FdTB9XGI2H1/keLFZHxl6WNvAI4YalHGtDQTlMnJcoqSab1UwL4l1hGEhs6/GmLHBZIg/YgB++jcbzoOEg==", - "dev": true, - "dependencies": { - "@jridgewell/source-map": "^0.3.2", - "acorn": "^8.5.0", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -15143,6 +16375,64 @@ "tree-kill": "cli.js" } }, + "node_modules/ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dev": true, + "peer": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/tsconfig-paths": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", + "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", + "dev": true, + "dependencies": { + "json5": "^2.2.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/tslib": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", @@ -15253,13 +16543,14 @@ "dev": true }, "node_modules/tuf-js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-1.1.3.tgz", - "integrity": "sha512-jGYi5nG/kqgfTFQSdoN6PW9eIn+XRZqdXku+fSwNk6UpWIsWaV7pzAqPgFr85edOPhoyJDyBqCS+DCnHroMvrw==", + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-1.1.6.tgz", + "integrity": "sha512-CXwFVIsXGbVY4vFiWF7TJKWmlKJAT8TWkH4RmiohJRcDJInix++F0dznDmoVbtJNzZ8yLprKUG4YrDIhv3nBMg==", "dev": true, "dependencies": { - "@tufjs/models": "1.0.2", - "make-fetch-happen": "^11.0.1" + "@tufjs/models": "1.0.4", + "debug": "^4.3.4", + "make-fetch-happen": "^11.1.0" }, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" @@ -15275,9 +16566,9 @@ } }, "node_modules/tuf-js/node_modules/make-fetch-happen": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-11.0.3.tgz", - "integrity": "sha512-oPLh5m10lRNNZDjJ2kP8UpboUx2uFXVaVweVe/lWut4iHWcQEmfqSVJt2ihZsFI8HbpwyyocaXbCAWf0g1ukIA==", + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz", + "integrity": "sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==", "dev": true, "dependencies": { "agentkeepalive": "^4.2.1", @@ -15287,7 +16578,7 @@ "https-proxy-agent": "^5.0.0", "is-lambda": "^1.0.1", "lru-cache": "^7.7.1", - "minipass": "^4.0.0", + "minipass": "^5.0.0", "minipass-fetch": "^3.0.0", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", @@ -15301,12 +16592,12 @@ } }, "node_modules/tuf-js/node_modules/minipass-fetch": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.1.tgz", - "integrity": "sha512-t9/wowtf7DYkwz8cfMSt0rMwiyNIBXf5CKZ3S5ZMqRqMYT0oLTp0x1WorMI9WTwvaPg21r1JbFxJMum8JrLGfw==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.3.tgz", + "integrity": "sha512-n5ITsTkDqYkYJZjcRWzZt9qnZKCT7nKCosJhHoj7S7zD+BP4jVbWs+odsniw5TA3E0sLomhTKOKjF86wf11PuQ==", "dev": true, "dependencies": { - "minipass": "^4.0.0", + "minipass": "^5.0.0", "minipass-sized": "^1.0.3", "minizlib": "^2.1.2" }, @@ -15475,12 +16766,12 @@ } }, "node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", "dev": true, "engines": { - "node": ">= 4.0.0" + "node": ">= 10.0.0" } }, "node_modules/unpipe": { @@ -15493,9 +16784,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", - "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", + "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", "dev": true, "funding": [ { @@ -15505,6 +16796,10 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "dependencies": { @@ -15512,7 +16807,7 @@ "picocolors": "^1.0.0" }, "bin": { - "browserslist-lint": "cli.js" + "update-browserslist-db": "cli.js" }, "peerDependencies": { "browserslist": ">= 4.21.0" @@ -15550,6 +16845,19 @@ "uuid": "dist/bin/uuid" } }, + "node_modules/v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true, + "peer": true + }, "node_modules/validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", @@ -15594,6 +16902,54 @@ "extsprintf": "^1.2.0" } }, + "node_modules/vite": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.3.1.tgz", + "integrity": "sha512-EPmfPLAI79Z/RofuMvkIS0Yr091T2ReUoXQqc5ppBX/sjFRhHKiPPF/R46cTdoci/XgeQpB23diiJxq5w30vdg==", + "dev": true, + "dependencies": { + "esbuild": "^0.17.5", + "postcss": "^8.4.21", + "rollup": "^3.20.2" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "@types/node": ">= 14", + "less": "*", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, "node_modules/void-elements": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", @@ -15783,22 +17139,22 @@ } }, "node_modules/webpack": { - "version": "5.76.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.76.1.tgz", - "integrity": "sha512-4+YIK4Abzv8172/SGqObnUjaIHjLEuUasz9EwQj/9xmPPkYJy2Mh03Q/lJfSD3YLzbxy5FeTq5Uw0323Oh6SJQ==", + "version": "5.80.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.80.0.tgz", + "integrity": "sha512-OIMiq37XK1rWO8mH9ssfFKZsXg4n6klTEDL7S8/HqbAOBBaiy8ABvXvz0dDCXeEF9gqwxSvVk611zFPjS8hJxA==", "dev": true, "dependencies": { "@types/eslint-scope": "^3.7.3", - "@types/estree": "^0.0.51", - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/wasm-edit": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", + "@types/estree": "^1.0.0", + "@webassemblyjs/ast": "^1.11.5", + "@webassemblyjs/wasm-edit": "^1.11.5", + "@webassemblyjs/wasm-parser": "^1.11.5", "acorn": "^8.7.1", "acorn-import-assertions": "^1.7.6", "browserslist": "^4.14.5", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.10.0", - "es-module-lexer": "^0.9.0", + "enhanced-resolve": "^5.13.0", + "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", @@ -15807,9 +17163,9 @@ "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "schema-utils": "^3.1.0", + "schema-utils": "^3.1.2", "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.3", + "terser-webpack-plugin": "^5.3.7", "watchpack": "^2.4.0", "webpack-sources": "^3.2.3" }, @@ -15830,9 +17186,9 @@ } }, "node_modules/webpack-dev-middleware": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-6.0.1.tgz", - "integrity": "sha512-PZPZ6jFinmqVPJZbisfggDiC+2EeGZ1ZByyMP5sOFJcPPWSexalISz+cvm+j+oYPT7FIJyxT76esjnw9DhE5sw==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-6.0.2.tgz", + "integrity": "sha512-iOddiJzPcQC6lwOIu60vscbGWth8PCRcWRCwoQcTQf9RMoOWBHg5EyzpGdtSmGMrSPd5vHEfFXmVErQEmkRngQ==", "dev": true, "dependencies": { "colorette": "^2.0.10", @@ -15850,12 +17206,17 @@ }, "peerDependencies": { "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + } } }, "node_modules/webpack-dev-server": { - "version": "4.11.1", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.11.1.tgz", - "integrity": "sha512-lILVz9tAUy1zGFwieuaQtYiadImb5M3d+H+L1zDYalYoDl0cksAB1UNyuE5MMWJrG6zR1tXkCP2fitl7yoUJiw==", + "version": "4.13.2", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.13.2.tgz", + "integrity": "sha512-5i6TrGBRxG4vnfDpB6qSQGfnB6skGBXNL5/542w2uRGLimX6qeE5BQMLrzIC3JYV/xlGOv+s+hTleI9AZKUQNw==", "dev": true, "dependencies": { "@types/bonjour": "^3.5.9", @@ -15877,6 +17238,7 @@ "html-entities": "^2.3.2", "http-proxy-middleware": "^2.0.3", "ipaddr.js": "^2.0.1", + "launch-editor": "^2.6.0", "open": "^8.0.9", "p-retry": "^4.5.0", "rimraf": "^3.0.2", @@ -15886,7 +17248,7 @@ "sockjs": "^0.3.24", "spdy": "^4.0.2", "webpack-dev-middleware": "^5.3.1", - "ws": "^8.4.2" + "ws": "^8.13.0" }, "bin": { "webpack-dev-server": "bin/webpack-dev-server.js" @@ -15902,6 +17264,9 @@ "webpack": "^4.37.0 || ^5.0.0" }, "peerDependenciesMeta": { + "webpack": { + "optional": true + }, "webpack-cli": { "optional": true } @@ -15930,6 +17295,27 @@ "webpack": "^4.0.0 || ^5.0.0" } }, + "node_modules/webpack-dev-server/node_modules/ws": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", + "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", + "dev": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/webpack-merge": { "version": "5.8.0", "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz", @@ -15973,12 +17359,6 @@ } } }, - "node_modules/webpack/node_modules/@types/estree": { - "version": "0.0.51", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", - "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==", - "dev": true - }, "node_modules/webpack/node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -16033,9 +17413,9 @@ "dev": true }, "node_modules/webpack/node_modules/schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.2.tgz", + "integrity": "sha512-pvjEHOgWc9OWA/f/DE3ohBWTD6EleVLf7iFUkoSwAxttdBhB9QUebQgxER2kWueOvRJXPHNnyrvvh9eZINB8Eg==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.8", @@ -16120,9 +17500,9 @@ } }, "node_modules/which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", + "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==" }, "node_modules/which-typed-array": { "version": "1.1.9", @@ -16154,9 +17534,9 @@ } }, "node_modules/wildcard": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", - "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", "dev": true }, "node_modules/word-wrap": { @@ -16184,6 +17564,57 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/wrap-ansi/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -16277,20 +17708,10 @@ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true }, - "node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, "node_modules/yargs": { - "version": "17.6.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", - "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", - "dev": true, + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -16308,11 +17729,33 @@ "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true, "engines": { "node": ">=12" } }, + "node_modules/yargs/node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/console/package.json b/console/package.json index 3606759df2..4e4fb35db2 100644 --- a/console/package.json +++ b/console/package.json @@ -3,7 +3,7 @@ "version": "0.0.0", "scripts": { "ng": "ng", - "start": "ng serve", + "start": "node prebuild.development.js && ng serve", "build": "ng build --configuration production --base-href=/ui/console/", "prelint": "npm run generate", "lint": "ng lint && prettier --check src", @@ -12,26 +12,23 @@ }, "private": true, "dependencies": { - "@angular/animations": "^15.2.6", - "@angular/cdk": "^15.2.6", - "@angular/common": "^15.2.6", - "@angular/compiler": "^15.2.6", - "@angular/core": "^15.2.6", - "@angular/forms": "^15.2.6", - "@angular/material": "^15.2.6", - "@angular/material-moment-adapter": "^15.2.6", - "@angular/platform-browser": "^15.2.6", - "@angular/platform-browser-dynamic": "^15.2.6", - "@angular/router": "^15.2.6", - "@angular/service-worker": "^15.2.6", + "@angular/animations": "^16.0.1", + "@angular/cdk": "^16.0.1", + "@angular/common": "^16.0.1", + "@angular/compiler": "^16.0.1", + "@angular/core": "^16.0.1", + "@angular/forms": "^16.0.1", + "@angular/material": "^16.0.1", + "@angular/material-moment-adapter": "^16.0.1", + "@angular/platform-browser": "^16.0.1", + "@angular/platform-browser-dynamic": "^16.0.1", + "@angular/router": "^16.0.1", + "@angular/service-worker": "^16.0.1", "@ctrl/ngx-codemirror": "^6.1.0", - "@grpc/grpc-js": "^1.8.12", + "@grpc/grpc-js": "^1.8.14", "@ngx-translate/core": "^14.0.0", - "@types/file-saver": "^2.0.2", - "@types/google-protobuf": "^3.15.3", - "@types/uuid": "^8.3.0", "angular-oauth2-oidc": "^15.0.1", - "angularx-qrcode": "^15.0.0", + "angularx-qrcode": "^16.0.0", "buffer": "^6.0.3", "codemirror": "^5.65.8", "cors": "^2.8.5", @@ -40,8 +37,8 @@ "google-proto-files": "^3.0.3", "google-protobuf": "^3.21.2", "grpc-web": "^1.4.1", - "i18n-iso-countries": "^7.5.0", - "libphonenumber-js": "^1.10.24", + "i18n-iso-countries": "^7.6.0", + "libphonenumber-js": "^1.10.30", "material-design-icons-iconfont": "^6.1.1", "moment": "^2.29.4", "ngx-color": "^8.0.3", @@ -52,35 +49,38 @@ "zone.js": "~0.13.0" }, "devDependencies": { - "@angular-devkit/build-angular": "^15.2.5", - "@angular-eslint/builder": "15.2.1", - "@angular-eslint/eslint-plugin": "15.2.1", - "@angular-eslint/eslint-plugin-template": "15.2.1", - "@angular-eslint/schematics": "15.2.1", - "@angular-eslint/template-parser": "15.2.1", - "@angular/cli": "^15.2.5", - "@angular/compiler-cli": "^15.2.6", - "@angular/language-service": "^15.2.6", - "@bufbuild/buf": "^1.14.0", + "@angular-devkit/build-angular": "^16.0.1", + "@angular-eslint/builder": "16.0.1", + "@angular-eslint/eslint-plugin": "16.0.1", + "@angular-eslint/eslint-plugin-template": "16.0.1", + "@angular-eslint/schematics": "16.0.1", + "@angular-eslint/template-parser": "16.0.1", + "@angular/cli": "^16.0.1", + "@angular/compiler-cli": "^16.0.1", + "@angular/language-service": "^16.0.1", + "@bufbuild/buf": "^1.18.0-1", + "@types/file-saver": "^2.0.2", + "@types/google-protobuf": "^3.15.3", "@types/jasmine": "~4.3.0", "@types/jasminewd2": "~2.0.10", "@types/jsonwebtoken": "^9.0.1", "@types/node": "^18.15.11", "@types/qrcode": "^1.5.0", - "@typescript-eslint/eslint-plugin": "5.48.2", - "@typescript-eslint/parser": "5.48.2", + "@types/uuid": "^9.0.1", + "@typescript-eslint/eslint-plugin": "^5.59.2", + "@typescript-eslint/parser": "^5.59.5", "codelyzer": "^6.0.2", - "eslint": "^8.33.0", + "eslint": "^8.39.0", "jasmine-core": "~4.6.0", "jasmine-spec-reporter": "~7.0.0", - "karma": "~6.4.1", - "karma-chrome-launcher": "~3.1.0", - "karma-coverage-istanbul-reporter": "~3.0.2", - "karma-jasmine": "~5.1.0", + "karma": "^6.4.2", + "karma-chrome-launcher": "^3.2.0", + "karma-coverage-istanbul-reporter": "^3.0.3", + "karma-jasmine": "^5.1.0", "karma-jasmine-html-reporter": "^2.0.0", "prettier": "^2.8.7", "prettier-plugin-organize-imports": "^3.2.2", "protractor": "~7.0.0", "typescript": "^4.9.5" } -} \ No newline at end of file +} diff --git a/console/prebuild.development.js b/console/prebuild.development.js new file mode 100644 index 0000000000..49a36a5efb --- /dev/null +++ b/console/prebuild.development.js @@ -0,0 +1,28 @@ +var fs = require('fs'); +var path = require('path') +var http = require('http'); +var https = require('https'); +var urlModule = require('url'); + +var defaultEnvironmentJsonURL = 'http://localhost:8080/ui/console/assets/environment.json' +var devEnvFile = path.join(__dirname, "src", "assets", "environment.json") +var url = process.env["ENVIRONMENT_JSON_URL"] || defaultEnvironmentJsonURL; + +var protocol = urlModule.parse(url).protocol; +var getter = protocol === 'https:' ? https.get : http.get; + +getter(url, function (res) { + var body = ''; + + res.on('data', function (chunk) { + body += chunk; + }); + + res.on('end', function () { + fs.writeFileSync(devEnvFile, body); + console.log("Developing against the following environment") + console.log(JSON.stringify(JSON.parse(body), null, 4)) + }); +}).on('error', function (e) { + console.error("Got an error: ", e); +}); diff --git a/console/src/app/app.module.ts b/console/src/app/app.module.ts index 2adbbbd8ec..adb60c8af9 100644 --- a/console/src/app/app.module.ts +++ b/console/src/app/app.module.ts @@ -1,5 +1,5 @@ import { CommonModule, registerLocaleData } from '@angular/common'; -import { HttpClientModule } from '@angular/common/http'; +import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http'; import localeDe from '@angular/common/locales/de'; import localeEn from '@angular/common/locales/en'; import localeEs from '@angular/common/locales/es'; @@ -27,7 +27,6 @@ import { RoleGuard } from 'src/app/guards/role.guard'; import { UserGuard } from 'src/app/guards/user.guard'; import { InfoOverlayModule } from 'src/app/modules/info-overlay/info-overlay.module'; import { AssetService } from 'src/app/services/asset.service'; - import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { HasRoleModule } from './directives/has-role/has-role.module'; @@ -40,9 +39,13 @@ import { HasRolePipeModule } from './pipes/has-role-pipe/has-role-pipe.module'; import { AdminService } from './services/admin.service'; import { AuthenticationService } from './services/authentication.service'; import { BreadcrumbService } from './services/breadcrumb.service'; +import { EnvironmentService } from './services/environment.service'; +import { ExhaustedService } from './services/exhausted.service'; import { GrpcAuthService } from './services/grpc-auth.service'; import { GrpcService } from './services/grpc.service'; import { AuthInterceptor } from './services/interceptors/auth.interceptor'; +import { ExhaustedGrpcInterceptor } from './services/interceptors/exhausted.grpc.interceptor'; +import { ExhaustedHttpInterceptor } from './services/interceptors/exhausted.http.interceptor'; import { GRPC_INTERCEPTORS } from './services/interceptors/grpc-interceptor'; import { I18nInterceptor } from './services/interceptors/i18n.interceptor'; import { OrgInterceptor } from './services/interceptors/org.interceptor'; @@ -84,9 +87,9 @@ export class WebpackTranslateLoader implements TranslateLoader { } } -const appInitializerFn = (grpcServ: GrpcService) => { +const appInitializerFn = (grpcSvc: GrpcService) => { return () => { - return grpcServ.loadAppEnvironment(); + return grpcSvc.loadAppEnvironment(); }; }; @@ -139,6 +142,8 @@ const authConfig: AuthConfig = { RoleGuard, UserGuard, ThemeService, + EnvironmentService, + ExhaustedService, { provide: APP_INITIALIZER, useFactory: appInitializerFn, @@ -167,6 +172,16 @@ const authConfig: AuthConfig = { provide: OAuthStorage, useClass: StorageService, }, + { + provide: HTTP_INTERCEPTORS, + multi: true, + useClass: ExhaustedHttpInterceptor, + }, + { + provide: GRPC_INTERCEPTORS, + multi: true, + useClass: ExhaustedGrpcInterceptor, + }, { provide: GRPC_INTERCEPTORS, multi: true, diff --git a/console/src/app/guards/auth.guard.ts b/console/src/app/guards/auth.guard.ts index 1b86cbebd8..ca996c3312 100644 --- a/console/src/app/guards/auth.guard.ts +++ b/console/src/app/guards/auth.guard.ts @@ -1,5 +1,5 @@ import { Injectable } from '@angular/core'; -import { ActivatedRouteSnapshot, CanActivate, RouterStateSnapshot } from '@angular/router'; +import { ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; import { AuthConfig } from 'angular-oauth2-oidc'; import { Observable } from 'rxjs'; @@ -8,7 +8,7 @@ import { AuthenticationService } from '../services/authentication.service'; @Injectable({ providedIn: 'root', }) -export class AuthGuard implements CanActivate { +export class AuthGuard { constructor(private auth: AuthenticationService) {} public canActivate( diff --git a/console/src/app/guards/role.guard.ts b/console/src/app/guards/role.guard.ts index 832a349961..951ffa1b60 100644 --- a/console/src/app/guards/role.guard.ts +++ b/console/src/app/guards/role.guard.ts @@ -1,5 +1,5 @@ import { Injectable } from '@angular/core'; -import { ActivatedRouteSnapshot, CanActivate, RouterStateSnapshot } from '@angular/router'; +import { ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; import { Observable } from 'rxjs'; import { GrpcAuthService } from '../services/grpc-auth.service'; @@ -7,7 +7,7 @@ import { GrpcAuthService } from '../services/grpc-auth.service'; @Injectable({ providedIn: 'root', }) -export class RoleGuard implements CanActivate { +export class RoleGuard { constructor(private authService: GrpcAuthService) {} public canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable { diff --git a/console/src/app/guards/user.guard.ts b/console/src/app/guards/user.guard.ts index df2b5b8c3b..8a037f2426 100644 --- a/console/src/app/guards/user.guard.ts +++ b/console/src/app/guards/user.guard.ts @@ -1,5 +1,5 @@ import { Injectable } from '@angular/core'; -import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router'; +import { ActivatedRouteSnapshot, Router, RouterStateSnapshot } from '@angular/router'; import { Observable } from 'rxjs'; import { map, tap } from 'rxjs/operators'; @@ -8,7 +8,7 @@ import { GrpcAuthService } from '../services/grpc-auth.service'; @Injectable({ providedIn: 'root', }) -export class UserGuard implements CanActivate { +export class UserGuard { constructor(private authService: GrpcAuthService, private router: Router) {} public canActivate( diff --git a/console/src/app/modules/footer/footer.component.ts b/console/src/app/modules/footer/footer.component.ts index 270128bdcf..b0fa971b08 100644 --- a/console/src/app/modules/footer/footer.component.ts +++ b/console/src/app/modules/footer/footer.component.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, OnInit } from '@angular/core'; import { PrivacyPolicy } from 'src/app/proto/generated/zitadel/policy_pb'; import { GrpcAuthService } from 'src/app/services/grpc-auth.service'; @@ -7,10 +7,12 @@ import { GrpcAuthService } from 'src/app/services/grpc-auth.service'; templateUrl: './footer.component.html', styleUrls: ['./footer.component.scss'], }) -export class FooterComponent { +export class FooterComponent implements OnInit { public policy?: PrivacyPolicy.AsObject; - constructor(public authService: GrpcAuthService) { - authService.getMyPrivacyPolicy().then((policyResp) => { + constructor(public authService: GrpcAuthService) {} + + ngOnInit(): void { + this.authService.getMyPrivacyPolicy().then((policyResp) => { if (policyResp.policy) { this.policy = policyResp.policy; } diff --git a/console/src/app/modules/header/header.component.html b/console/src/app/modules/header/header.component.html index fe5306256f..002efa3b0d 100644 --- a/console/src/app/modules/header/header.component.html +++ b/console/src/app/modules/header/header.component.html @@ -228,7 +228,6 @@ (detach)="showAccount = false" > = new Subject(); public BreadcrumbType: any = BreadcrumbType; - public customerPortalLink: string = ''; + public customerPortalLink$ = this.envService.env.pipe(map((env) => env.customer_portal)); public positions: ConnectedPosition[] = [ new ConnectionPositionPair({ originX: 'start', originY: 'bottom' }, { overlayX: 'start', overlayY: 'top' }, 0, 10), @@ -98,6 +98,7 @@ export class NavComponent implements OnDestroy { ]; constructor( + private envService: EnvironmentService, public authService: GrpcAuthService, public adminService: AdminService, public authenticationService: AuthenticationService, @@ -105,23 +106,9 @@ export class NavComponent implements OnDestroy { public mgmtService: ManagementService, private router: Router, private breakpointObserver: BreakpointObserver, - private http: HttpClient, private shortcutService: KeyboardShortcutsService, private storageService: StorageService, - ) { - this.loadEnvironment(); - } - - public loadEnvironment(): void { - this.http - .get('./assets/environment.json') - .pipe(take(1)) - .subscribe((data: any) => { - if (data && data.customer_portal) { - this.customerPortalLink = data.customer_portal; - } - }); - } + ) {} public ngOnDestroy() { this.destroy$.next(); diff --git a/console/src/app/pages/orgs/org.module.ts b/console/src/app/pages/orgs/org.module.ts index a9a68bff59..d2857329fe 100644 --- a/console/src/app/pages/orgs/org.module.ts +++ b/console/src/app/pages/orgs/org.module.ts @@ -6,7 +6,6 @@ import { MatLegacyButtonModule as MatButtonModule } from '@angular/material/lega import { MatLegacyDialogModule as MatDialogModule } from '@angular/material/legacy-dialog'; import { MatLegacyMenuModule as MatMenuModule } from '@angular/material/legacy-menu'; import { MatLegacyProgressSpinnerModule as MatProgressSpinnerModule } from '@angular/material/legacy-progress-spinner'; -import { MatLegacyTabsModule as MatTabsModule } from '@angular/material/legacy-tabs'; import { MatLegacyTooltipModule as MatTooltipModule } from '@angular/material/legacy-tooltip'; import { TranslateModule } from '@ngx-translate/core'; import { CopyToClipboardModule } from 'src/app/directives/copy-to-clipboard/copy-to-clipboard.module'; @@ -47,7 +46,6 @@ import { OrgRoutingModule } from './org-routing.module'; MatIconModule, ReactiveFormsModule, MetaLayoutModule, - MatTabsModule, MatTooltipModule, WarnDialogModule, MemberCreateDialogModule, diff --git a/console/src/app/pages/projects/apps/app-create/app-create.component.html b/console/src/app/pages/projects/apps/app-create/app-create.component.html index ab75a2c8f6..a487adcc1e 100644 --- a/console/src/app/pages/projects/apps/app-create/app-create.component.html +++ b/console/src/app/pages/projects/apps/app-create/app-create.component.html @@ -2,14 +2,16 @@ title="{{ 'APP.PAGES.CREATE' | translate }}" class="app-create-wrapper" [createSteps]=" - appType?.value?.createType === AppCreateType.OIDC - ? appType?.value.oidcAppType !== OIDCAppType.OIDC_APP_TYPE_NATIVE - ? 4 - : 3 - : appType?.value?.createType === AppCreateType.API - ? 3 - : appType?.value?.createType === AppCreateType.SAML - ? 3 + !devmode + ? appType?.value?.createType === AppCreateType.OIDC + ? appType?.value.oidcAppType !== OIDCAppType.OIDC_APP_TYPE_NATIVE + ? 4 + : 3 + : appType?.value?.createType === AppCreateType.API + ? 3 + : appType?.value?.createType === AppCreateType.SAML + ? 3 + : 0 : 0 " [currentCreateStep]="currentCreateStep" diff --git a/console/src/app/pages/projects/apps/app-detail/app-detail.component.html b/console/src/app/pages/projects/apps/app-detail/app-detail.component.html index 0d69f370d0..67ea50c6ed 100644 --- a/console/src/app/pages/projects/apps/app-detail/app-detail.component.html +++ b/console/src/app/pages/projects/apps/app-detail/app-detail.component.html @@ -397,8 +397,8 @@ - - + +
-
+

{{ wellKnownV.key }}

diff --git a/console/src/app/pages/projects/apps/app-detail/app-detail.component.ts b/console/src/app/pages/projects/apps/app-detail/app-detail.component.ts index d02eaa7769..2f743acb73 100644 --- a/console/src/app/pages/projects/apps/app-detail/app-detail.component.ts +++ b/console/src/app/pages/projects/apps/app-detail/app-detail.component.ts @@ -1,6 +1,5 @@ import { COMMA, ENTER, SPACE } from '@angular/cdk/keycodes'; import { Location } from '@angular/common'; -import { HttpClient } from '@angular/common/http'; import { Component, OnDestroy, OnInit } from '@angular/core'; import { AbstractControl, FormControl, UntypedFormBuilder, UntypedFormControl, UntypedFormGroup } from '@angular/forms'; import { MatLegacyCheckboxChange as MatCheckboxChange } from '@angular/material/legacy-checkbox'; @@ -10,7 +9,7 @@ import { TranslateService } from '@ngx-translate/core'; import { Buffer } from 'buffer'; import { Duration } from 'google-protobuf/google/protobuf/duration_pb'; import { Subject, Subscription } from 'rxjs'; -import { take } from 'rxjs/operators'; +import { map, take } from 'rxjs/operators'; import { RadioItemAuthType } from 'src/app/modules/app-radio/app-auth-method-radio/app-auth-method-radio.component'; import { ChangeType } from 'src/app/modules/changes/changes.component'; import { InfoSectionType } from 'src/app/modules/info-section/info-section.component'; @@ -41,6 +40,7 @@ import { GrpcAuthService } from 'src/app/services/grpc-auth.service'; import { ManagementService } from 'src/app/services/mgmt.service'; import { ToastService } from 'src/app/services/toast.service'; +import { EnvironmentService } from 'src/app/services/environment.service'; import { AppSecretDialogComponent } from '../app-secret-dialog/app-secret-dialog.component'; import { BASIC_AUTH_METHOD, @@ -79,8 +79,17 @@ export class AppDetailComponent implements OnInit, OnDestroy { public projectId: string = ''; public app?: App.AsObject; - public environmentMap: { [key: string]: string } = {}; - public wellKnownMap: { [key: string]: string } = {}; + public environmentMap$ = this.envSvc.env.pipe( + map((env) => { + return { + issuer: env.issuer, + adminServiceUrl: `${env.api}/admin/v1`, + mgmtServiceUrl: `${env.api}/management/v1`, + authServiceUrl: `${env.api}/auth/v1`, + }; + }), + ); + public wellKnownMap$ = this.envSvc.wellKnown; public oidcResponseTypes: OIDCResponseType[] = [ OIDCResponseType.OIDC_RESPONSE_TYPE_CODE, @@ -138,6 +147,7 @@ export class AppDetailComponent implements OnInit, OnDestroy { public currentSetting: string | undefined = this.settingsList[0].id; constructor( + private envSvc: EnvironmentService, public translate: TranslateService, private route: ActivatedRoute, private toast: ToastService, @@ -148,7 +158,6 @@ export class AppDetailComponent implements OnInit, OnDestroy { private authService: GrpcAuthService, private router: Router, private breadcrumbService: BreadcrumbService, - private http: HttpClient, ) { this.oidcForm = this.fb.group({ devMode: [{ value: false, disabled: true }], @@ -176,25 +185,6 @@ export class AppDetailComponent implements OnInit, OnDestroy { metadataUrl: [{ value: '', disabled: true }], metadataXml: [{ value: '', disabled: true }], }); - - this.http.get('./assets/environment.json').subscribe((env: any) => { - this.environmentMap = { - issuer: env.issuer, - adminServiceUrl: `${env.api}/admin/v1`, - mgmtServiceUrl: `${env.api}/management/v1`, - authServiceUrl: `${env.api}/auth/v1`, - }; - - this.http.get(`${env.issuer}/.well-known/openid-configuration`).subscribe((wellKnown: any) => { - this.wellKnownMap = { - authorization_endpoint: wellKnown.authorization_endpoint, - end_session_endpoint: wellKnown.end_session_endpoint, - introspection_endpoint: wellKnown.introspection_endpoint, - token_endpoint: wellKnown.token_endpoint, - userinfo_endpoint: wellKnown.userinfo_endpoint, - }; - }); - }); } public formatClockSkewLabel(seconds: number): string { diff --git a/console/src/app/pages/projects/granted-projects/granted-projects.module.ts b/console/src/app/pages/projects/granted-projects/granted-projects.module.ts index 1ebf27e545..e334959efa 100644 --- a/console/src/app/pages/projects/granted-projects/granted-projects.module.ts +++ b/console/src/app/pages/projects/granted-projects/granted-projects.module.ts @@ -9,7 +9,6 @@ import { MatLegacyProgressBarModule as MatProgressBarModule } from '@angular/mat import { MatLegacyProgressSpinnerModule as MatProgressSpinnerModule } from '@angular/material/legacy-progress-spinner'; import { MatLegacySelectModule as MatSelectModule } from '@angular/material/legacy-select'; import { MatLegacyTableModule as MatTableModule } from '@angular/material/legacy-table'; -import { MatLegacyTabsModule as MatTabsModule } from '@angular/material/legacy-tabs'; import { MatLegacyTooltipModule as MatTooltipModule } from '@angular/material/legacy-tooltip'; import { MatSortModule } from '@angular/material/sort'; import { TranslateModule } from '@ngx-translate/core'; @@ -51,7 +50,6 @@ import { GrantedProjectsRoutingModule } from './granted-projects-routing.module' MatIconModule, MatSelectModule, MatButtonModule, - MatTabsModule, MatProgressSpinnerModule, MetaLayoutModule, MatProgressBarModule, diff --git a/console/src/app/pages/projects/owned-projects/owned-project-detail/owned-project-detail.module.ts b/console/src/app/pages/projects/owned-projects/owned-project-detail/owned-project-detail.module.ts index 9d4a66c1d3..2698a206cd 100644 --- a/console/src/app/pages/projects/owned-projects/owned-project-detail/owned-project-detail.module.ts +++ b/console/src/app/pages/projects/owned-projects/owned-project-detail/owned-project-detail.module.ts @@ -9,7 +9,6 @@ import { MatLegacyMenuModule as MatMenuModule } from '@angular/material/legacy-m import { MatLegacyProgressSpinnerModule as MatProgressSpinnerModule } from '@angular/material/legacy-progress-spinner'; import { MatLegacySelectModule as MatSelectModule } from '@angular/material/legacy-select'; import { MatLegacyTableModule as MatTableModule } from '@angular/material/legacy-table'; -import { MatLegacyTabsModule as MatTabsModule } from '@angular/material/legacy-tabs'; import { MatLegacyTooltipModule as MatTooltipModule } from '@angular/material/legacy-tooltip'; import { TranslateModule } from '@ngx-translate/core'; import { HasRoleModule } from 'src/app/directives/has-role/has-role.module'; @@ -53,7 +52,6 @@ import { OwnedProjectDetailComponent } from './owned-project-detail.component'; MatIconModule, InfoRowModule, ContributorsModule, - MatTabsModule, WarnDialogModule, MatTooltipModule, ProjectRolesTableModule, diff --git a/console/src/app/pages/projects/projects.module.ts b/console/src/app/pages/projects/projects.module.ts index 901f37f64a..3f8c0afd4e 100644 --- a/console/src/app/pages/projects/projects.module.ts +++ b/console/src/app/pages/projects/projects.module.ts @@ -6,7 +6,7 @@ import { MatIconModule } from '@angular/material/icon'; import { MatLegacyButtonModule as MatButtonModule } from '@angular/material/legacy-button'; import { MatLegacyCheckboxModule as MatCheckboxModule } from '@angular/material/legacy-checkbox'; import { MatLegacyProgressSpinnerModule as MatProgressSpinnerModule } from '@angular/material/legacy-progress-spinner'; -import { MatLegacyTableModule as MatTableModule } from '@angular/material/legacy-table'; +import { MatLegacyTableModule } from '@angular/material/legacy-table'; import { MatLegacyTooltipModule as MatTooltipModule } from '@angular/material/legacy-tooltip'; import { MatSortModule } from '@angular/material/sort'; import { TranslateModule } from '@ngx-translate/core'; @@ -36,7 +36,7 @@ import { ProjectsComponent } from './projects.component'; TranslateModule, FormsModule, HasRoleModule, - MatTableModule, + MatLegacyTableModule, PaginatorModule, InputModule, MatIconModule, diff --git a/console/src/app/pages/users/user-detail/user-detail.module.ts b/console/src/app/pages/users/user-detail/user-detail.module.ts index 289b6a68a5..47e96f70bf 100644 --- a/console/src/app/pages/users/user-detail/user-detail.module.ts +++ b/console/src/app/pages/users/user-detail/user-detail.module.ts @@ -8,7 +8,6 @@ import { MatLegacyDialogModule as MatDialogModule } from '@angular/material/lega import { MatLegacyMenuModule as MatMenuModule } from '@angular/material/legacy-menu'; import { MatLegacyProgressSpinnerModule as MatProgressSpinnerModule } from '@angular/material/legacy-progress-spinner'; import { MatLegacyTableModule as MatTableModule } from '@angular/material/legacy-table'; -import { MatLegacyTabsModule as MatTabsModule } from '@angular/material/legacy-tabs'; import { MatLegacyTooltipModule as MatTooltipModule } from '@angular/material/legacy-tooltip'; import { RouterModule } from '@angular/router'; import { TranslateModule } from '@ngx-translate/core'; @@ -87,7 +86,6 @@ import { UserMfaComponent } from './user-detail/user-mfa/user-mfa.component'; ChangesModule, CommonModule, SidenavModule, - MatTabsModule, FormsModule, ReactiveFormsModule, MembershipsTableModule, diff --git a/console/src/app/services/asset.service.ts b/console/src/app/services/asset.service.ts index 25e6ba1df7..320150ff46 100644 --- a/console/src/app/services/asset.service.ts +++ b/console/src/app/services/asset.service.ts @@ -1,9 +1,10 @@ import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; -import { lastValueFrom } from 'rxjs'; +import { switchMap } from 'rxjs'; import { PolicyComponentServiceType } from '../modules/policies/policy-component-types.enum'; import { Theme } from '../modules/policies/private-labeling-policy/private-labeling-policy.component'; +import { EnvironmentService } from './environment.service'; import { StorageService } from './storage.service'; const authorizationKey = 'Authorization'; @@ -69,46 +70,29 @@ export const ENDPOINT = { providedIn: 'root', }) export class AssetService { - private serviceUrl!: Promise; private accessToken: string = ''; - constructor(private http: HttpClient, private storageService: StorageService) { + constructor(private envService: EnvironmentService, private http: HttpClient, private storageService: StorageService) { const aT = this.storageService.getItem(accessTokenStorageKey); - if (aT) { this.accessToken = aT; } - this.serviceUrl = this.getServiceUrl(); - } - - private async getServiceUrl(): Promise { - const url = await lastValueFrom(this.http.get('./assets/environment.json')) - .then((data: any) => { - if (data && data.api) { - return data.api; - } - }) - .catch((error) => { - console.error(error); - }); - - return url; } public upload(endpoint: AssetEndpoint | string, body: any, orgId?: string): Promise { const headers: any = { [authorizationKey]: `${bearerPrefix} ${this.accessToken}`, }; - if (orgId) { headers[orgKey] = `${orgId}`; } - - return this.serviceUrl.then((url) => - this.http - .post(`${url}/assets/v1/${endpoint}`, body, { - headers: headers, - }) - .toPromise(), - ); + return this.envService.env + .pipe( + switchMap((env) => + this.http.post(`${env.api}/assets/v1/${endpoint}`, body, { + headers: headers, + }), + ), + ) + .toPromise(); } } diff --git a/console/src/app/services/authentication.service.ts b/console/src/app/services/authentication.service.ts index b4b24c30fd..c5de101e68 100644 --- a/console/src/app/services/authentication.service.ts +++ b/console/src/app/services/authentication.service.ts @@ -35,10 +35,8 @@ export class AuthenticationService { Object.assign(this.authConfig, partialConfig); } this.oauthService.configure(this.authConfig); - this.oauthService.strictDiscoveryDocumentValidation = false; await this.oauthService.loadDiscoveryDocumentAndTryLogin(); - this._authenticated = this.oauthService.hasValidAccessToken(); if (!this.oauthService.hasValidIdToken() || !this.authenticated || partialConfig || force) { const newState = await lastValueFrom(this.statehandler.createState()); diff --git a/console/src/app/services/environment.service.ts b/console/src/app/services/environment.service.ts new file mode 100644 index 0000000000..343cd424b4 --- /dev/null +++ b/console/src/app/services/environment.service.ts @@ -0,0 +1,88 @@ +import { HttpClient } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { catchError, map, Observable, of, shareReplay, switchMap, throwError } from 'rxjs'; + +import { AdminServiceClient } from '../proto/generated/zitadel/AdminServiceClientPb'; +import { AuthServiceClient } from '../proto/generated/zitadel/AuthServiceClientPb'; +import { ManagementServiceClient } from '../proto/generated/zitadel/ManagementServiceClientPb'; +import { ExhaustedService } from './exhausted.service'; + +export interface Environment { + api: string; + clientid: string; + issuer: string; + customer_portal?: string; + instance_management_url?: string; + exhausted?: boolean; +} + +interface WellKnown { + authorization_endpoint: string; + end_session_endpoint: string; + introspection_endpoint: string; + token_endpoint: string; + userinfo_endpoint: string; +} +@Injectable({ + providedIn: 'root', +}) +export class EnvironmentService { + private environmentJsonPath = './assets/environment.json'; + private wellknownPath = '/.well-known/openid-configuration`'; + public auth!: AuthServiceClient; + public mgmt!: ManagementServiceClient; + public admin!: AdminServiceClient; + + private environment$: Observable; + private wellKnown$: Observable; + + constructor(private http: HttpClient, private exhaustedSvc: ExhaustedService) { + this.environment$ = this.createEnvironment(); + this.wellKnown$ = this.createWellKnown(this.environment$); + } + + // env returns an `Observable` that can be subscribed to whenever needed. + // It makes the HTTP call exactly once and replays the cached result. + // If the responses exhausted property is true, the exhaused dialog is shown. + get env() { + return this.environment$; + } + + // wellKnown returns an `Observable` that can be subscribed to whenever needed. + // It makes the HTTP call exactly once and replays the cached result. + get wellKnown() { + return this.wellKnown$; + } + + private createEnvironment() { + return this.http.get(this.environmentJsonPath).pipe( + catchError((err) => { + console.error('Getting environment.json failed', err); + return throwError(() => err); + }), + switchMap((env) => { + const env$ = of(env); + if (env.exhausted) { + return this.exhaustedSvc.showExhaustedDialog(env$).pipe(map(() => env)); + } + return env$; + }), + // Cache the first response, then replay it + shareReplay(1), + ); + } + + private createWellKnown(environment$: Observable) { + return environment$.pipe( + catchError((err) => { + console.error('Getting well-known OIDC configuration failed', err); + return throwError(() => err); + }), + switchMap((env) => { + return this.http.get(`${env.issuer}${this.wellknownPath}`); + }), + // Cache the first response, then replay it + shareReplay(1), + ); + } +} diff --git a/console/src/app/services/exhausted.service.ts b/console/src/app/services/exhausted.service.ts new file mode 100644 index 0000000000..135e30e5f9 --- /dev/null +++ b/console/src/app/services/exhausted.service.ts @@ -0,0 +1,41 @@ +import { Injectable } from '@angular/core'; +import { MatLegacyDialog as MatDialog } from '@angular/material/legacy-dialog'; +import { map, Observable, of, switchMap, tap } from 'rxjs'; +import { WarnDialogComponent } from '../modules/warn-dialog/warn-dialog.component'; +import { Environment } from './environment.service'; + +@Injectable({ + providedIn: 'root', +}) +export class ExhaustedService { + private isClosed = true; + + constructor(private dialog: MatDialog) {} + + public showExhaustedDialog(env$: Observable) { + if (!this.isClosed) { + return of(undefined); + } + this.isClosed = false; + return this.dialog + .open(WarnDialogComponent, { + data: { + confirmKey: 'ACTIONS.CONTINUE', + titleKey: 'ERRORS.EXHAUSTED.TITLE', + descriptionKey: 'ERRORS.EXHAUSTED.DESCRIPTION', + }, + disableClose: true, + width: '400px', + id: 'authenticated-requests-exhausted-dialog', + }) + .afterClosed() + .pipe( + switchMap(() => env$), + tap((env) => { + // Just reload if there is no instance management url + location.href = env.instance_management_url || location.href; + }), + map(() => undefined), + ); + } +} diff --git a/console/src/app/services/grpc.service.ts b/console/src/app/services/grpc.service.ts index 9dc4a84807..a842edfb2a 100644 --- a/console/src/app/services/grpc.service.ts +++ b/console/src/app/services/grpc.service.ts @@ -1,18 +1,22 @@ import { PlatformLocation } from '@angular/common'; -import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { MatLegacyDialog as MatDialog } from '@angular/material/legacy-dialog'; import { TranslateService } from '@ngx-translate/core'; import { AuthConfig } from 'angular-oauth2-oidc'; +import { catchError, switchMap, tap, throwError } from 'rxjs'; import { AdminServiceClient } from '../proto/generated/zitadel/AdminServiceClientPb'; import { AuthServiceClient } from '../proto/generated/zitadel/AuthServiceClientPb'; import { ManagementServiceClient } from '../proto/generated/zitadel/ManagementServiceClientPb'; import { AuthenticationService } from './authentication.service'; +import { EnvironmentService } from './environment.service'; +import { ExhaustedService } from './exhausted.service'; import { AuthInterceptor } from './interceptors/auth.interceptor'; +import { ExhaustedGrpcInterceptor } from './interceptors/exhausted.grpc.interceptor'; import { I18nInterceptor } from './interceptors/i18n.interceptor'; import { OrgInterceptor } from './interceptors/org.interceptor'; import { StorageService } from './storage.service'; +import { ThemeService } from './theme.service'; @Injectable({ providedIn: 'root', @@ -23,22 +27,30 @@ export class GrpcService { public admin!: AdminServiceClient; constructor( - private http: HttpClient, + private envService: EnvironmentService, private platformLocation: PlatformLocation, private authenticationService: AuthenticationService, private storageService: StorageService, private dialog: MatDialog, private translate: TranslateService, + private exhaustedService: ExhaustedService, + private themeService: ThemeService, ) {} - public async loadAppEnvironment(): Promise { - return this.http - .get('./assets/environment.json') - .toPromise() - .then((data: any) => { - if (data && data.api && data.issuer) { + public loadAppEnvironment(): Promise { + this.themeService.applyLabelPolicy(); + // We use the browser language until we can make API requests to get the users configured language. + return this.translate + .use(this.translate.getBrowserLang() || this.translate.defaultLang) + .pipe( + switchMap(() => this.envService.env), + tap((env) => { + if (!env?.api || !env?.issuer) { + return; + } const interceptors = { unaryInterceptors: [ + new ExhaustedGrpcInterceptor(this.exhaustedService, this.envService), new OrgInterceptor(this.storageService), new AuthInterceptor(this.authenticationService, this.storageService, this.dialog), new I18nInterceptor(this.translate), @@ -46,19 +58,19 @@ export class GrpcService { }; this.auth = new AuthServiceClient( - data.api, + env.api, null, // @ts-ignore interceptors, ); this.mgmt = new ManagementServiceClient( - data.api, + env.api, null, // @ts-ignore interceptors, ); this.admin = new AdminServiceClient( - data.api, + env.api, null, // @ts-ignore interceptors, @@ -68,19 +80,20 @@ export class GrpcService { scope: 'openid profile email', responseType: 'code', oidc: true, - clientId: data.clientid, - issuer: data.issuer, + clientId: env.clientid, + issuer: env.issuer, redirectUri: window.location.origin + this.platformLocation.getBaseHrefFromDOM() + 'auth/callback', postLogoutRedirectUri: window.location.origin + this.platformLocation.getBaseHrefFromDOM() + 'signedout', requireHttps: false, }; this.authenticationService.initConfig(authConfig); - } - return Promise.resolve(data); - }) - .catch(() => { - console.error('Failed to load environment from assets'); - }); + }), + catchError((err) => { + console.error('Failed to load environment from assets', err); + return throwError(() => err); + }), + ) + .toPromise(); } } diff --git a/console/src/app/services/interceptors/auth.interceptor.ts b/console/src/app/services/interceptors/auth.interceptor.ts index 18f85fbb0c..5ff77dcad8 100644 --- a/console/src/app/services/interceptors/auth.interceptor.ts +++ b/console/src/app/services/interceptors/auth.interceptor.ts @@ -43,7 +43,7 @@ export class AuthInterceptor implements UnaryIn .then((response: any) => { return response; }) - .catch((error: any) => { + .catch(async (error: any) => { if (error.code === 16) { this.triggerDialog.next(true); } diff --git a/console/src/app/services/interceptors/exhausted.grpc.interceptor.ts b/console/src/app/services/interceptors/exhausted.grpc.interceptor.ts new file mode 100644 index 0000000000..7486b525ca --- /dev/null +++ b/console/src/app/services/interceptors/exhausted.grpc.interceptor.ts @@ -0,0 +1,29 @@ +import { Injectable } from '@angular/core'; +import { Request, StatusCode, UnaryInterceptor, UnaryResponse } from 'grpc-web'; +import { EnvironmentService } from '../environment.service'; +import { ExhaustedService } from '../exhausted.service'; + +/** + * ExhaustedGrpcInterceptor shows the exhausted dialog after receiving a gRPC response status 8. + */ +@Injectable({ providedIn: 'root' }) +export class ExhaustedGrpcInterceptor implements UnaryInterceptor { + constructor(private exhaustedSvc: ExhaustedService, private envSvc: EnvironmentService) {} + + public async intercept( + request: Request, + invoker: (request: Request) => Promise>, + ): Promise> { + return invoker(request).catch((error: any) => { + if (error.code === StatusCode.RESOURCE_EXHAUSTED) { + return this.exhaustedSvc + .showExhaustedDialog(this.envSvc.env) + .toPromise() + .then(() => { + throw error; + }); + } + throw error; + }); + } +} diff --git a/console/src/app/services/interceptors/exhausted.http.interceptor.ts b/console/src/app/services/interceptors/exhausted.http.interceptor.ts new file mode 100644 index 0000000000..898f9ccd98 --- /dev/null +++ b/console/src/app/services/interceptors/exhausted.http.interceptor.ts @@ -0,0 +1,24 @@ +import { HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { catchError, Observable, switchMap, throwError } from 'rxjs'; +import { EnvironmentService } from '../environment.service'; +import { ExhaustedService } from '../exhausted.service'; + +/** + * ExhaustedHttpInterceptor shows the exhausted dialog after receiving an HTTP response status 429. + */ +@Injectable() +export class ExhaustedHttpInterceptor implements HttpInterceptor { + constructor(private exhaustedSvc: ExhaustedService, private envSvc: EnvironmentService) {} + + intercept(req: HttpRequest, next: HttpHandler): Observable> { + return next.handle(req).pipe( + catchError((error: HttpErrorResponse) => { + if (error.status === 429) { + return this.exhaustedSvc.showExhaustedDialog(this.envSvc.env).pipe(switchMap(() => throwError(() => error))); + } + return throwError(() => error); + }), + ); + } +} diff --git a/console/src/app/services/interceptors/http-org.interceptor.ts b/console/src/app/services/interceptors/http-org.interceptor.ts deleted file mode 100644 index 9531e14711..0000000000 --- a/console/src/app/services/interceptors/http-org.interceptor.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http'; -import { OAuthModuleConfig } from 'angular-oauth2-oidc'; -import { Observable } from 'rxjs'; - -import { Org } from '../../proto/generated/zitadel/org_pb'; -import { StorageKey, StorageLocation, StorageService } from '../storage.service'; - -const orgKey = 'x-zitadel-orgid'; -export abstract class HttpOrgInterceptor implements HttpInterceptor { - private org!: Org.AsObject; - - protected get validUrls(): string[] { - return this.oauthModuleConfig.resourceServer.allowedUrls || []; - } - - constructor(private storageService: StorageService, protected oauthModuleConfig: OAuthModuleConfig) { - const org: Org.AsObject | null = this.storageService.getItem(StorageKey.organization, StorageLocation.session); - - if (org) { - this.org = org; - } - } - - public intercept(req: HttpRequest, next: HttpHandler): Observable> { - if (!this.urlValidation(req.url)) { - return next.handle(req); - } - - return next.handle( - req.clone({ - setHeaders: { - [orgKey]: this.org.id, - }, - }), - ); - } - - private urlValidation(toIntercept: string): boolean { - const URLS = ['https://api.zitadel.dev/assets', 'https://api.zitadel.ch/assets']; - - return URLS.findIndex((url) => toIntercept.startsWith(url)) > -1; - } -} diff --git a/console/src/assets/i18n/de.json b/console/src/assets/i18n/de.json index b4fbe919e8..68d81ac777 100644 --- a/console/src/assets/i18n/de.json +++ b/console/src/assets/i18n/de.json @@ -252,6 +252,10 @@ "TITLE": "Du bist abgemeldet", "DESCRIPTION": "Klicke auf \"Einloggen\", um Dich erneut anzumelden." }, + "EXHAUSTED": { + "TITLE": "Dein Kontingent an authentifizierten Anfragen is erschöpft.", + "DESCRIPTION": "Lösche oder erhöhe die Grenze für diese ZITADEL Instanz." + }, "INVALID_FORMAT": "Das Format is ungültig.", "NOTANEMAIL": "Der eingegebene Wert ist keine E-Mail Adresse.", "MINLENGTH": "Muss mindestens {{requiredLength}} Zeichen lang sein.", diff --git a/console/src/assets/i18n/en.json b/console/src/assets/i18n/en.json index 586d21db07..2d27939ee0 100644 --- a/console/src/assets/i18n/en.json +++ b/console/src/assets/i18n/en.json @@ -253,6 +253,10 @@ "TITLE": "Your authorization token has expired.", "DESCRIPTION": "Click the button below to log in again." }, + "EXHAUSTED": { + "TITLE": "Your quota for authenticated requests is exhausted.", + "DESCRIPTION": "Remove or increase the quota limit for this ZITADEL instance." + }, "INVALID_FORMAT": "The formatting is invalid.", "NOTANEMAIL": "The given value is not an e-mail address.", "MINLENGTH": "Must be at least {{requiredLength}} characters long.", diff --git a/console/src/assets/i18n/es.json b/console/src/assets/i18n/es.json index 80ce39bc6f..0fea6748ab 100644 --- a/console/src/assets/i18n/es.json +++ b/console/src/assets/i18n/es.json @@ -253,6 +253,10 @@ "TITLE": "Tu token de autorización token ha caducado.", "DESCRIPTION": "Haz clic en el botón más abajo para iniciar sesión otra vez." }, + "EXHAUSTED": { + "TITLE": "Su cuota de solicitudes autenticadas se ha agotado.", + "DESCRIPTION": "Borrar o aumentar el límite de esta instancia de ZITADEL." + }, "INVALID_FORMAT": "El formato no es valido.", "NOTANEMAIL": "El valor proporcionado no es una dirección de email.", "MINLENGTH": "Debe tener al menos {{requiredLength}} caracteres de longitud.", diff --git a/console/src/assets/i18n/fr.json b/console/src/assets/i18n/fr.json index a95736564f..e24116fd80 100644 --- a/console/src/assets/i18n/fr.json +++ b/console/src/assets/i18n/fr.json @@ -252,6 +252,10 @@ "TITLE": "Votre jeton d'autorisation a expiré.", "DESCRIPTION": "Cliquez sur le bouton ci-dessous pour vous reconnecter." }, + "EXHAUSTED": { + "TITLE": "Ton quota de demandes authentifiées est épuisé.", + "DESCRIPTION": "Supprimez ou augmentez la limite de cette instance ZITADEL." + }, "INVALID_FORMAT": "Le format n'est pas valide", "NOTANEMAIL": "La valeur donnée n'est pas une adresse e-mail", "MINLENGTH": "Doit comporter au moins {{length}} caractères.", diff --git a/console/src/assets/i18n/it.json b/console/src/assets/i18n/it.json index 113252814e..4d18722afb 100644 --- a/console/src/assets/i18n/it.json +++ b/console/src/assets/i18n/it.json @@ -252,6 +252,10 @@ "TITLE": "Il tuo Access Token \u00e8 scaduto.", "DESCRIPTION": "Clicca il pulsante per richiedere una nuova sessione." }, + "EXHAUSTED": { + "TITLE": "La quota di richieste autenticate è esaurita.", + "DESCRIPTION": "Cancellare o aumentare il limite per questa istanza ZITADEL." + }, "INVALID_FORMAT": "Il formato non è valido.", "NOTANEMAIL": "Il valore dato non \u00e8 un indirizzo e-mail.", "MINLENGTH": "Deve essere lunga almeno {{requiredLength}} caratteri.", diff --git a/console/src/assets/i18n/ja.json b/console/src/assets/i18n/ja.json index 8c3e33d224..2ba3863ad4 100644 --- a/console/src/assets/i18n/ja.json +++ b/console/src/assets/i18n/ja.json @@ -253,6 +253,10 @@ "TITLE": "トークンが期限切れになりました。", "DESCRIPTION": "下のボタンをクリックして、もう一度ログインする。" }, + "EXHAUSTED": { + "TITLE": "認証されたリクエストのクォータを使い果たしました", + "DESCRIPTION": "このZITADELインスタンスの制限を削除または増加させる" + }, "INVALID_FORMAT": "不正なフォーマットです", "NOTANEMAIL": "入力された値がメールアドレスではありません。", "MINLENGTH": "{{requiredLength}} 文字以上の文字列が必要です。", diff --git a/console/src/assets/i18n/pl.json b/console/src/assets/i18n/pl.json index fc480d2853..0dd538ba30 100644 --- a/console/src/assets/i18n/pl.json +++ b/console/src/assets/i18n/pl.json @@ -252,6 +252,10 @@ "TITLE": "Twój token autoryzacji wygasł.", "DESCRIPTION": "Kliknij przycisk poniżej, aby ponownie się zalogować." }, + "EXHAUSTED": { + "TITLE": "Twój limit uwierzytelnionych wniosków został wyczerpany.", + "DESCRIPTION": "Usuń lub zwiększ limit dla tej instancji ZITADEL." + }, "INVALID_FORMAT": "Format jest nieprawidłowy.", "NOTANEMAIL": "Podana wartość nie jest adresem e-mail.", "MINLENGTH": "Musi mieć co najmniej {{requiredLength}} znaków.", diff --git a/console/src/assets/i18n/zh.json b/console/src/assets/i18n/zh.json index bfd30edfae..dbc8dcc199 100644 --- a/console/src/assets/i18n/zh.json +++ b/console/src/assets/i18n/zh.json @@ -252,6 +252,10 @@ "TITLE": "您的授权令牌已过期。", "DESCRIPTION": "点击下方按钮再次登录。" }, + "EXHAUSTED": { + "TITLE": "你的认证请求配额已用完.", + "DESCRIPTION": "删除或增加这个ZITADEL实例的限制。" + }, "INVALID_FORMAT": "格式是无效的。", "NOTANEMAIL": "给定的值不是合法电子邮件地址。", "MINLENGTH": "长度必须至少是{{requiredLength}}字符。", diff --git a/docs/.gitignore b/docs/.gitignore index aa32254704..7e8329214f 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -9,6 +9,9 @@ .cache-loader .artifacts +# Generated by docusaurus-plugin-openapi-docs +docs/apis/resources + # Misc .DS_Store .env.local diff --git a/docs/docs/apis/introduction.mdx b/docs/docs/apis/introduction.mdx index 66c767b6f4..c17048083e 100644 --- a/docs/docs/apis/introduction.mdx +++ b/docs/docs/apis/introduction.mdx @@ -1,5 +1,6 @@ --- -title: Overview +title: API Reference Overview +sidebar_label: Overview --- import { ApiCard } from "../../src/components/apicard"; @@ -50,7 +51,7 @@ Endpoint: $ZITADEL_DOMAIN/auth/v1/ API Reference: -[OpenAPI Docs](/apis/auth) +[OpenAPI Docs](/apis/resources/auth)
@@ -83,7 +84,7 @@ Endpoint: $ZITADEL_DOMAIN/management/v1/ API Reference: -[OpenAPI Docs](/apis/mgmt) +[OpenAPI Docs](/apis/resources/mgmt)
@@ -114,7 +115,7 @@ Endpoint: $ZITADEL_DOMAIN/admin/v1/ API Reference: -[OpenAPI Docs](/apis/admin) +[OpenAPI Docs](/apis/resources/admin)
@@ -147,7 +148,7 @@ Endpoint: $ZITADEL_DOMAIN/system/v1/ API Reference: -[OpenAPI Docs](/apis/system) +[OpenAPI Docs](/apis/resources/system)
diff --git a/docs/docs/concepts/architecture/software.md b/docs/docs/concepts/architecture/software.md index 81e9a09107..29dcb2c1ea 100644 --- a/docs/docs/concepts/architecture/software.md +++ b/docs/docs/concepts/architecture/software.md @@ -145,4 +145,7 @@ The storage layer of ZITADEL is responsible for multiple things. For example: - Backup and restore operation for disaster recovery purpose ZITADEL currently supports CockroachDB as first choice of storage due to its perfect match for ZITADELs needs. -PostgreSQL support is currently in beta. +Postgres is currently in [Beta](/docs/support/software-release-cycles-support#beta) and will be [Enterprise Supported](/docs/support/software-release-cycles-support#partially-supported) afterwards. +Beta state will be removed as soon as [automated tests](https://github.com/zitadel/zitadel/issues/5741) are implemented. +Make sure to read our [Production Guide](./self-hosting/manage/production#prefer-cockroachdb) before you decide to use it. + diff --git a/docs/docs/concepts/architecture/solution.md b/docs/docs/concepts/architecture/solution.md index bad19063b2..176c151732 100644 --- a/docs/docs/concepts/architecture/solution.md +++ b/docs/docs/concepts/architecture/solution.md @@ -9,8 +9,9 @@ Since the storage layer takes the heavy lifting of making sure that data in sync Depending on your projects needs our general recommendation is to run ZITADEL and ZITADELs storage layer across multiple availability zones in the same region or if you need higher guarantees run the storage layer across multiple regions. Consult the [CockroachDB documentation](https://www.cockroachlabs.com/docs/) for more details or use the [CockroachCloud Service](https://www.cockroachlabs.com/docs/cockroachcloud/create-an-account.html) - -> Postgres support of ZITADEL is currently in beta. +Postgres is currently in [Beta](/docs/support/software-release-cycles-support#beta) and will be [Enterprise Supported](/docs/support/software-release-cycles-support#partially-supported) afterwards. +Beta state will be removed as soon as [automated tests](https://github.com/zitadel/zitadel/issues/5741) are implemented. +Make sure to read our [Production Guide](./self-hosting/manage/production#prefer-cockroachdb) before you decide to use it. ## Scalability diff --git a/docs/docs/concepts/eventstore/overview.md b/docs/docs/concepts/eventstore/overview.md index a3e1719cb0..fd564ce96b 100644 --- a/docs/docs/concepts/eventstore/overview.md +++ b/docs/docs/concepts/eventstore/overview.md @@ -1,5 +1,6 @@ --- -title: Overview +title: Eventstore +sidebar_label: Overview --- ZITADEL is built on the [Event Sourcing pattern](../architecture/software), where changes are stored as events in an Event Store. diff --git a/docs/docs/concepts/features/audit-trail.md b/docs/docs/concepts/features/audit-trail.md index 8b7136a22a..bf1992453d 100644 --- a/docs/docs/concepts/features/audit-trail.md +++ b/docs/docs/concepts/features/audit-trail.md @@ -35,7 +35,7 @@ Go to your instance settings and then click on the Tab **Events** to open the Ev Since everything that is available in Console can also be called with our APIs, you can access all events and audit data trough our APIs: - [Event API Guide](/docs/guides/integrate/event-api) -- [API Documentation](/docs/category/apis/admin/events) +- [API Documentation](/docs/category/apis/resources/admin/events) Access to the API is possible with a [Service User](/docs/guides/integrate/serviceusers) account, allowing you to integrate the events with your own business logic. diff --git a/docs/docs/concepts/features/selfservice.md b/docs/docs/concepts/features/selfservice.md index 043011b422..1a664e4bce 100644 --- a/docs/docs/concepts/features/selfservice.md +++ b/docs/docs/concepts/features/selfservice.md @@ -151,7 +151,7 @@ The current password must be entered first. Users can setup and delete a second factor and FIDO Passkeys (Passwordless). Available authenticators are: -- Mobile one-time password (OTP) (Authenticator Apps, SMS) +- Mobile one-time password (OTP) (Authenticator Apps) - FIDO Universal Second Factor (U2F) (Security Keys, Device, etc.) - FIDO2 WebAuthN (Passkeys) diff --git a/docs/docs/concepts/introduction.mdx b/docs/docs/concepts/introduction.mdx deleted file mode 100644 index ed94e66444..0000000000 --- a/docs/docs/concepts/introduction.mdx +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: Introduction ---- - -This part of the **ZITADEL** documentation contains ZITADEL specific or general concepts required to understand the system or our guides. - -![Overview](/img/concepts/objects/object_overview.png) - -This overview shows the general structure of ZITADEL. -You will find more detailed explanations around the different concepts in the following sections. \ No newline at end of file diff --git a/docs/docs/concepts/structure/instance.mdx b/docs/docs/concepts/structure/instance.mdx index ce4eb99530..d407ab679d 100644 --- a/docs/docs/concepts/structure/instance.mdx +++ b/docs/docs/concepts/structure/instance.mdx @@ -14,13 +14,18 @@ which in turn can represent your own company (e.g. departments), your business c Read more about how to configure your instance in our [instance guide](/guides/manage/console/instance-settings). -![Two instances with each organizations in it using the same database](/img/concepts/objects/instances.png) +![Overview](/img/concepts/objects/object_overview.png) + +This overview shows the general structure of ZITADEL. +You will find more detailed explanations around the different concepts in the following sections. ## Multiple Virtual Instances ZITADEL has the concept of virtual instances. When installing ZITADEL from scratch, one instance is always automatically created for you. -Nevertheless, you can add more virtual instances via the [system API](/apis/system). +Nevertheless, you can add more virtual instances via the [system API](/apis/resources/system). This is useful if you have business customers, which in turn have their business customers with self service and custom domain demands. By providing a virtual ZITADEL instances, your customers have all the customization options available in ZITADEL. Scaling ZITADEL instances virtually enables you to easily distribute your limited compute resources to all your customers. + +![Two instances with each organizations in it using the same database](/img/concepts/objects/instances.png) diff --git a/docs/docs/concepts/structure/overview.md b/docs/docs/concepts/structure/overview.md deleted file mode 100644 index c2d6d23151..0000000000 --- a/docs/docs/concepts/structure/overview.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: Overview ---- - -This overview shows the general structure of ZITADEL. - -![Overview](/img/concepts/objects/object_overview.png) - -More details on the specific objects: - -- [Instance](./instance) -- [Organizations](./organizations) -- [Policies/Settings](./policies) -- [Projects](./projects) -- [Applications](./applications) -- [Granted Projects](./granted_projects) -- [Users](./users) diff --git a/docs/docs/examples/introduction.mdx b/docs/docs/examples/introduction.mdx index 873bf42a99..b29c5bcb2d 100644 --- a/docs/docs/examples/introduction.mdx +++ b/docs/docs/examples/introduction.mdx @@ -1,12 +1,13 @@ --- -title: Overview +title: Overview of examples, quickstarts, and SDKs +sidebar_label: Overview --- Our examples cover a range of programming languages and frameworks, so no matter what you're into, we've got you covered. ## Frontend -### Single Page Application +### Single page application @@ -45,7 +46,7 @@ Our examples cover a range of programming languages and frameworks, so no matter
-### Native / Mobile App +### Native/mobile app @@ -66,7 +67,7 @@ Our examples cover a range of programming languages and frameworks, so no matter
-### Regular Web App +### Regular web app diff --git a/docs/docs/examples/login/angular.md b/docs/docs/examples/login/angular.md index 833c10317f..3eaa9ca2c6 100644 --- a/docs/docs/examples/login/angular.md +++ b/docs/docs/examples/login/angular.md @@ -2,50 +2,51 @@ title: Angular --- -This integration guide shows you the recommended way to integrate ZITADEL into your Angular application. -It shows how to add user login to your application and fetch some data from the user info endpoint. +This integration guide demonstrates the recommended way to incorporate ZITADEL into your Angular application. +It explains how to enable user login in your application and how to fetch data from the user info endpoint. -At the end of the guide, your application has login functionality and has access to the current user's profile. +By the end of this guide, your application will have login functionality and will be able to access the current user's profile. -> This documentation refers to our [example](https://github.com/zitadel/zitadel-angular) in GitHub. Note that we've written ZITADEL Console in Angular, so you can also use that as a reference. +> This documentation references our [example](https://github.com/zitadel/zitadel-angular) on GitHub. Please note that we wrote the ZITADEL Console in Angular, so you can also use that as a reference. -## Setup Application and Get Keys +## Set up application and obtain keys -Before we can start building our application, we have to do a few configuration steps in ZITADEL Console. -You will need to provide some information about your app. We recommend creating a new app to start from scratch. Navigate to your Project, then add a new application at the top of the page. -Select **User Agent** application type and continue. -We recommend you use [Proof Key for Code Exchange (PKCE)](/apis/openidoauth/grant-types#proof-key-for-code-exchange) for all SPA applications. +Before we begin developing our application, we need to perform a few configuration steps in the ZITADEL Console. +You'll need to provide some information about your app. We recommend creating a new app to start from scratch. Navigate to your Project, then add a new application at the top of the page. +Select the **User Agent** application type and continue. +We recommend that you use [Proof Key for Code Exchange (PKCE)](/apis/openidoauth/grant-types#proof-key-for-code-exchange) for all SPA applications. ![Create app in console](/img/angular/app-create.png) + ### Redirect URIs -With the Redirect URIs field, you tell ZITADEL where it is allowed to redirect users to after authentication. For development, you can set dev mode to `true` to enable insecure HTTP and redirect to a `localhost` URI. -The Post logout redirect send the users back to a route on your application after they have logged out. +The Redirect URIs field tells ZITADEL where it's allowed to redirect users after authentication. For development, you can set dev mode to `true` to enable insecure HTTP and redirect to a `localhost` URI. +The Post-logout redirect send the users back to a route on your application after they have logged out. -> If you are following along with the [example](https://github.com/zitadel/zitadel-angular), set dev mode to `true`, the Redirect URIs to and Post redirect URI to . +> If you are following along with the [example](https://github.com/zitadel/zitadel-angular), set the dev mode to `true`, the Redirect URIs to and Post redirect URI to . Continue and create the application. ### Client ID -After successful app creation, a pop-up will appear, showing the app's client ID. Copy the client ID, as you will need it to configure your Angular client. +After successful creation of the app, a pop-up will appear displaying the app's client ID. Copy the client ID, as you will need it to configure your Angular client. -## Angular Setup +## Angular setup -Now that you have your web application configured on the ZITADEL side, you can go ahead and integrate your Angular client. +Now that you have configured your web application on the ZITADEL side, you can proceed with the integration of your Angular client. -### Install Angular Dependencies +### Install Angular dependencies -You need to install an OAuth / OIDC client to connect with ZITADEL. Run the following command: +To connect with ZITADEL, you need to install an OAuth/OIDC client. Run the following command: ```bash npm install angular-oauth2-oidc ``` -### Create and Configure Auth Module +### Create and configure the auth module -Add _OAuthModule_ to your Angular imports in _AppModule_ and provide the _AuthConfig_ in the providers' section. Also, ensure you import the _HTTPClientModule_. +Add _OAuthModule_ to your Angular imports in _AppModule_ and provide the _AuthConfig_ in the providers' section. Also, ensure that you import the _HTTPClientModule_. ```ts reference https://github.com/zitadel/zitadel-angular/blob/main/src/app/app.module.ts @@ -59,20 +60,18 @@ You can use Angular’s schematics to do so: ng g service services/authentication ``` -Copy the following code to your service. This code provides a function `authenticate()` which redirects the user to ZITADEL. After successful login, ZITADEL redirects the user back to the redirect URI configured in _AuthModule_ and ZITADEL Console. Make sure both correspond, otherwise ZITADEL throws an error. +Copy the following code to your service. This code provides a function `authenticate()`, which redirects the user to ZITADEL. After a successful login, ZITADEL redirects the user back to the redirect URI configured in _AuthModule_ and ZITADEL Console. Ensure that both correspond, otherwise ZITADEL will throw an error. ```ts reference https://github.com/zitadel/zitadel-angular/blob/main/src/app/services/authentication.service.ts ``` -Our example includes a _StatehandlerService_ to redirect the user back to the route where he initially came from. -If you don't need such behavior, you can omit the following line from the `authenticate()` method above. +Our example includes a _StatehandlerService_ that redirects the user back to the route from which they initially came.If you don't need such behavior, you can omit the following line from the `authenticate()` method above. ```ts reference https://github.com/zitadel/zitadel-angular/blob/main/src/app/services/authentication.service.ts#L45 ``` - -If you decide to use the _StatehandlerService_, provide it in the `app.module`. Make sure it gets initialized first using Angular’s `APP_INITIALIZER`. You find the service implementation in the [example](https://github.com/zitadel/zitadel-angular). +If you decide to use the _StatehandlerService_, include it in the `app.module`. Ensure it gets initialized first using Angular’s `APP_INITIALIZER`. You can find the service implementation in the [example](https://github.com/zitadel/zitadel-angular). ```ts reference https://github.com/zitadel/zitadel-angular/blob/main/src/app/app.module.ts#L26-L30 @@ -82,15 +81,14 @@ https://github.com/zitadel/zitadel-angular/blob/main/src/app/app.module.ts#L26-L https://github.com/zitadel/zitadel-angular/blob/main/src/app/app.module.ts#L55-L78 ``` -### Add Login to Your Application +### Add login to your application -To log a user in, you need a component or a guard. +To log in a user, you need a component or a guard. -- A component could provide a button, starting the login flow on click. +- A component could provide a button that initiates the login flow when clicked. +- A guard initiates a login flow when a user without a stored valid access token attempts to access a protected route. -- A guard that starts a login flow once a user without a stored valid access token tries to access a protected route. - -Using these components heavily depends on your application. In most cases, you need both. +The use of these components depends heavily on your application. In most cases, you need both. Generate a component like this: @@ -100,8 +98,7 @@ ng g component components/login Inject the _AuthenticationService_ and call `authenticate()` on some click event. -Same for the guard: - +Do the same for the guard: ```bash ng g guard guards/auth ``` @@ -118,23 +115,23 @@ Add the guard to your _RouterModule_ similar to this: https://github.com/zitadel/zitadel-angular/blob/main/src/app/app-routing.module.ts#L9-L31 ``` -> Note: Make sure you redirect the user from your callback URL to a guarded page, so `authenticate()` is called again and the access token is stored. +> Note: Make sure you redirect the user from your callback URL to a guarded page, so the `authenticate()` method is called again, and the access token is stored. ```ts reference https://github.com/zitadel/zitadel-angular/blob/main/src/app/app-routing.module.ts#L19-L21 ``` -### Add Logout to Your Application +### Add logout to your application -Call `auth.signout()` for logging the current user out. Note that you can also configure a logout redirect URI if you want your users to be redirected after logout. +Call `auth.signout()` to log out the current user. Keep in mind that you can also configure a logout redirect URI if you want your users to be redirected after logout. ```ts reference https://github.com/zitadel/zitadel-angular/blob/main/src/app/components/user/user.component.ts#L20-L22 ``` -### Show User Information +### Display user information -To fetch user data, ZITADEL's user info endpoint has to be called. This data contains sensitive information and artifacts related to the current user's identity and the scopes you defined in your _AuthConfig_. +To fetch user data, you need to call the ZITADEL's user info endpoint. This data contains sensitive information and artifacts related to the current user's identity and the scopes you defined in your _AuthConfig_. Our _AuthenticationService_ already includes a method called _getOIDCUser()_. You can call it wherever you need this information. ```ts reference @@ -149,25 +146,26 @@ https://github.com/zitadel/zitadel-angular/blob/main/src/app/components/user/use ### Refresh token -If you want to add a refresh token to your application you have to navigate to the console application and tick the checkbox in the configuration section. -Then add `offline_access` to the scopes and add the line +If you want to add a refresh token to your application, navigate to the console application and check the box in the configuration section. +Then add `offline_access` to the scopes and add the following line: ``` this.oauthService.setupAutomaticSilentRefresh(); ``` -this will automatically refresh a token before it expires. +This line automatically refreshes a token before it expires. + ## Completion -You have successfully integrated your Angular application with ZITADEL! +Congratulations! You have successfully integrated your Angular application with ZITADEL! -If you get stuck, consider checking out our [example](https://github.com/zitadel/zitadel-angular) application. It includes all the mentioned functionality of this quickstart. You can simply start by cloning the repository and replacing the _AuthConfig_ in the _AppModule_ by your own configuration. If you run into issues, contact us or raise an issue on [GitHub](https://github.com/zitadel/zitadel). +If you get stuck, consider checking out our [example](https://github.com/zitadel/zitadel-angular) application. This application includes all the funcationalities mentioned in this quickstart. You can start by cloning the repository and replacing the _AuthConfig_ in the _AppModule_ with your own configuration. If you face issues, contact us or raise an issue on [GitHub](https://github.com/zitadel/zitadel). ![App in console](/img/angular/app-screen.png) ### What's next? -Now that you have enabled authentication, it's time to add authorization to your application using ZITADEL APIs. Refer to the [docs](/apis/introduction) or check out our ZITADEL Console code on [GitHub](https://github.com/zitadel/zitadel) which is using gRPC to access data. +Now that you have enabled authentication, it's time for you to add authorization to your application using ZITADEL APIs. To do this, you can refer to the [docs](/apis/introduction) or check out the ZITADEL Console code on [GitHub](https://github.com/zitadel/zitadel) which uses gRPC to access data. -For more information about creating an Angular application, refer to [Angular](https://angular.io/start) and for more information about the OAuth/OIDC library used above, consider reading their docs at [angular-oauth2-oidc](https://github.com/manfredsteyer/angular-oauth2-oidc). +For more information on how to create an Angular application, you can refer to [Angular](https://angular.io/start). If you want to learn more about the OAuth/OIDC library used above, consider reading the docs at [angular-oauth2-oidc](https://github.com/manfredsteyer/angular-oauth2-oidc). \ No newline at end of file diff --git a/docs/docs/examples/sdks.md b/docs/docs/examples/sdks.md index 53a639bd88..6c70dba163 100644 --- a/docs/docs/examples/sdks.md +++ b/docs/docs/examples/sdks.md @@ -13,6 +13,71 @@ title: SDKs | Python | 🚧 [WIP](https://github.com/zitadel/zitadel/issues/3675) | ❓ | ❓ | TBD | | NodeJS | [@zitadel/node](https://www.npmjs.com/package/@zitadel/node) | ❌ | ✔️ | `community` | +## Missing an SDK + +Is your language/framework missing? Fear not, you can generate your gRPC API Client with ease. + +1. Make sure to install [buf](https://buf.build/docs/installation/) +2. Create a `buf.gen.yaml` and configure the [plugins](https://buf.build/plugins) you need +3. Run `buf generate https://github.com/zitadel/zitadel#format=git,tag=v2.23.1` (change the versions to your needs) + +Let us make an example with Ruby. Any other supported language by buf will work as well. Consult the [buf plugin registry](https://buf.build/plugins) for more ideas. + +### Example with Ruby + +With gRPC we usually need to generate the client stub and the messages/types. This is why we need two plugins. +The plugin `grpc/ruby` generates the client stub and the plugin `protocolbuffers/ruby` takes care of the messages/types. + +```yaml +version: v1 +plugins: + - plugin: buf.build/grpc/ruby + out: gen + - plugin: buf.build/protocolbuffers/ruby + out: gen +``` + +If you now run `buf generate https://github.com/zitadel/zitadel#format=git,tag=v2.23.1` in the folder where your `buf.gen.yaml` is located you should see the folder `gen` appear. + +If you run `ls -la gen/zitadel/` you should see something like this: + +```bash +ffo@ffo-pc:~/git/zitadel/ruby$ ls -la gen/zitadel/ +total 704 +drwxr-xr-x 2 ffo ffo 4096 Apr 11 16:49 . +drwxr-xr-x 3 ffo ffo 4096 Apr 11 16:49 .. +-rw-r--r-- 1 ffo ffo 4397 Apr 11 16:49 action_pb.rb +-rw-r--r-- 1 ffo ffo 141097 Apr 11 16:49 admin_pb.rb +-rw-r--r-- 1 ffo ffo 25151 Apr 11 16:49 admin_services_pb.rb +-rw-r--r-- 1 ffo ffo 6537 Apr 11 16:49 app_pb.rb +-rw-r--r-- 1 ffo ffo 1134 Apr 11 16:49 auth_n_key_pb.rb +-rw-r--r-- 1 ffo ffo 32881 Apr 11 16:49 auth_pb.rb +-rw-r--r-- 1 ffo ffo 6896 Apr 11 16:49 auth_services_pb.rb +-rw-r--r-- 1 ffo ffo 1571 Apr 11 16:49 change_pb.rb +-rw-r--r-- 1 ffo ffo 2488 Apr 11 16:49 event_pb.rb +-rw-r--r-- 1 ffo ffo 14782 Apr 11 16:49 idp_pb.rb +-rw-r--r-- 1 ffo ffo 5031 Apr 11 16:49 instance_pb.rb +-rw-r--r-- 1 ffo ffo 223348 Apr 11 16:49 management_pb.rb +-rw-r--r-- 1 ffo ffo 44402 Apr 11 16:49 management_services_pb.rb +-rw-r--r-- 1 ffo ffo 3020 Apr 11 16:49 member_pb.rb +-rw-r--r-- 1 ffo ffo 855 Apr 11 16:49 message_pb.rb +-rw-r--r-- 1 ffo ffo 1445 Apr 11 16:49 metadata_pb.rb +-rw-r--r-- 1 ffo ffo 2370 Apr 11 16:49 object_pb.rb +-rw-r--r-- 1 ffo ffo 621 Apr 11 16:49 options_pb.rb +-rw-r--r-- 1 ffo ffo 4425 Apr 11 16:49 org_pb.rb +-rw-r--r-- 1 ffo ffo 8538 Apr 11 16:49 policy_pb.rb +-rw-r--r-- 1 ffo ffo 8223 Apr 11 16:49 project_pb.rb +-rw-r--r-- 1 ffo ffo 1022 Apr 11 16:49 quota_pb.rb +-rw-r--r-- 1 ffo ffo 5872 Apr 11 16:49 settings_pb.rb +-rw-r--r-- 1 ffo ffo 20985 Apr 11 16:49 system_pb.rb +-rw-r--r-- 1 ffo ffo 4784 Apr 11 16:49 system_services_pb.rb +-rw-r--r-- 1 ffo ffo 28759 Apr 11 16:49 text_pb.rb +-rw-r--r-- 1 ffo ffo 24170 Apr 11 16:49 user_pb.rb +-rw-r--r-- 1 ffo ffo 13568 Apr 11 16:49 v1_pb.rb +``` + +Import these files into your project to start interacting with ZITADEL's APIs. + ## More While we are not actively maintaining the following projects, it is worth checking out if you're interested in exploring ZITADEL in different programming languages or frameworks. diff --git a/docs/docs/guides/integrate/access-zitadel-system-api.md b/docs/docs/guides/integrate/access-zitadel-system-api.md index e8297b64ae..598a096dc7 100644 --- a/docs/docs/guides/integrate/access-zitadel-system-api.md +++ b/docs/docs/guides/integrate/access-zitadel-system-api.md @@ -145,7 +145,7 @@ You should get a successful response with a `totalResult` number of 1 and the de } ``` -With this token you are allowed to access the whole [ZITADEL System API](/apis/system). +With this token you are allowed to access the whole [ZITADEL System API](/apis/resources/system). ## Summary diff --git a/docs/docs/guides/integrate/event-api.md b/docs/docs/guides/integrate/event-api.md index c47a7342fb..bf0f8d43c0 100644 --- a/docs/docs/guides/integrate/event-api.md +++ b/docs/docs/guides/integrate/event-api.md @@ -11,7 +11,7 @@ You need to give a user the [manager role](https://zitadel.com/docs/guides/manag If you like to know more about eventsourcing/eventstore and how this works in ZITADEL, head over to our [concepts](../../concepts/eventstore/overview). ## Request Events -Call the [ListEvents](/apis/admin) enpoint in the Administration API to get all the events you need. +Call the [ListEvents](/apis/resources/admin) enpoint in the Administration API to get all the events you need. To further restrict your result you can add the following filters: - sequence - editor user id @@ -29,7 +29,7 @@ curl --request POST \ ## Get event types -To be able to filter for the different event types ZITADEL knows, you can request the [EventTypesList](/apis/admin) +To be able to filter for the different event types ZITADEL knows, you can request the [EventTypesList](/apis/resources/admin) ```bash curl --request POST \ @@ -65,7 +65,7 @@ The following example shows you the event types for a password check (failed/suc ## Get aggregate types -To be able to filter for the different aggregate types (resources) ZITADEL knows, you can request the [AggregateTypesList](/apis/admin) +To be able to filter for the different aggregate types (resources) ZITADEL knows, you can request the [AggregateTypesList](/apis/resources/admin) ```bash curl --request POST \ diff --git a/docs/docs/guides/integrate/private-key-jwt.md b/docs/docs/guides/integrate/private-key-jwt.md index a02f48b376..227af7a8e7 100644 --- a/docs/docs/guides/integrate/private-key-jwt.md +++ b/docs/docs/guides/integrate/private-key-jwt.md @@ -15,7 +15,7 @@ This is a guide on how to create service users in ZITADEL. You can read more abo In ZITADEL we use the `urn:ietf:params:oauth:grant-type:jwt-bearer` (**“JWT bearer token with private key”**, [RFC7523](https://tools.ietf.org/html/rfc7523)) authorization grant for this non-interactive authentication. -You need to follow these steps to authenticate a service user and receive a access token: +You need to follow these steps to authenticate a service user and receive an access token: 1. Generate a private-public key pair in ZITADEL 2. Create a JSON Web Token (JWT) and sign with private key @@ -25,7 +25,7 @@ With this token you can make subsequent requests, just like a human user. ## Get an access token -In this step we will authenticate a service user and receive an access_token to use against a API. +In this step we will authenticate a service user and receive an access_token to use against the API. > **Information:** Are you stuck? Don't hesitate to reach out to us on [Github Discussions](https://github.com/zitadel/zitadel/discussions) or [contact us](https://zitadel.com/contact/) privately. @@ -96,6 +96,8 @@ curl --request POST \ --data assertion=eyJ0eXAiOiJKV1QiL... ``` +If you want to access the ZITADEL API with this access token, you have to add `urn:zitadel:iam:org:project:id:zitadel:aud` to the list of scopes. + * `grant_type` should be set to `urn:ietf:params:oauth:grant-type:jwt-bearer` * `scope` should contain any [Scopes](/apis/openidoauth/scopes) you want to include, but must include `openid`. For this example, please include `profile` and `email` * `assertion` is the encoded value of the JWT that was signed with your private key from the prior step diff --git a/docs/docs/guides/manage/cloud/overview.md b/docs/docs/guides/manage/cloud/overview.md deleted file mode 100644 index 8c144f571e..0000000000 --- a/docs/docs/guides/manage/cloud/overview.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -title: Overview ---- - -The ZITADEL customer Portal is used to manage all your different ZITADEL instances. -You can also manage your subscriptions, billing, newsletters and support requests. - -More details on the specific objects: - -- [Getting Started](./start) -- [Instances](./instances) -- [Billing](./billing) -- [Users](./users) -- [Support](./support) diff --git a/docs/docs/guides/manage/cloud/support.md b/docs/docs/guides/manage/cloud/support.md index f62cbbb63f..7ccebbe555 100644 --- a/docs/docs/guides/manage/cloud/support.md +++ b/docs/docs/guides/manage/cloud/support.md @@ -2,6 +2,9 @@ title: Support --- +:::note +We describe our [support services](/docs/legal/support-services) and information required in more detail in our legal section. Beware that not all features may be supported by your subscription and consult the [support states](/docs/support/software-release-cycles-support#support-states). +::: In the header you can find a button for the support. Create a new support request with the following information: diff --git a/docs/docs/guides/manage/console/overview.mdx b/docs/docs/guides/manage/console/overview.mdx index 9553f06b55..3e515ffa0d 100644 --- a/docs/docs/guides/manage/console/overview.mdx +++ b/docs/docs/guides/manage/console/overview.mdx @@ -1,5 +1,6 @@ --- -title: Overview +title: Console +sidebar_label: Overview --- ## What is console? diff --git a/docs/docs/guides/manage/customize/texts.md b/docs/docs/guides/manage/customize/texts.md index 1609e2a93e..d090115950 100644 --- a/docs/docs/guides/manage/customize/texts.md +++ b/docs/docs/guides/manage/customize/texts.md @@ -5,6 +5,7 @@ title: Customized Texts You are able to customize the texts used from ZITADEL. This is possibly on the instance or organization level. ## Message Texts + Sometimes the users will get an email or phone message from ZITADEL (e.g Password Reset Request). ZITADEL already has some good standard texts, but maybe you would like to customize it for your organization. @@ -29,7 +30,7 @@ You will see the default texts in the input field and you can overwrite them by If you don't like your customization anymore click the "reset policy" button. All your settings will be removed and the default settings of the system will trigger. -## Internationalization +## Internationalization / i18n ZITADEL is available in the following languages diff --git a/docs/docs/guides/manage/user/reg-create-user.md b/docs/docs/guides/manage/user/reg-create-user.md index 5a889ff904..0ac85e3b33 100644 --- a/docs/docs/guides/manage/user/reg-create-user.md +++ b/docs/docs/guides/manage/user/reg-create-user.md @@ -6,7 +6,7 @@ The ZITADEL API has different possibilities to create users. This can be used, if you are building your own registration page. Use the following API call to create your users: -[Create User (Human)](/apis/mgmt/management-service-import-human-user.api.mdx) +[Create User (Human)](/apis/resources/mgmt/management-service-import-human-user.api.mdx) ## With Username and Password @@ -31,7 +31,7 @@ If nothing is requested, the type will not be restricted and all possibilities o If you already have a user in ZITADEL, it is possible to add passwordless later. -[Add Passwordless Registration ](/apis/mgmt) +[Add Passwordless Registration ](/apis/resources/mgmt) Send the user_id in the request and you will get a link and an expiration as response. You can then customize the link the same as described above in the creation process. @@ -39,7 +39,7 @@ You can then customize the link the same as described above in the creation proc The second possibility is to send the link directly to the user per email. Use the following request in that case: -[Send Passwordless Registration ](/apis/mgmt) +[Send Passwordless Registration ](/apis/resources/mgmt) ## Verified Email Address diff --git a/docs/docs/guides/migrate/users.md b/docs/docs/guides/migrate/users.md index c01bbfb380..713293d6f3 100644 --- a/docs/docs/guides/migrate/users.md +++ b/docs/docs/guides/migrate/users.md @@ -7,7 +7,7 @@ Migrating users from an existing system, while minimizing impact on said users, ## Individual Users -Creating individual users can be done with this endpoint: [ImportHumanUser](/docs/apis/mgmt/management-service-import-human-user). +Creating individual users can be done with this endpoint: [ImportHumanUser](/docs/apis/resources/mgmt/management-service-import-human-user). Please also consult our [guide](/docs/guides/manage/user/reg-create-user) on how to create users. ```json @@ -42,7 +42,7 @@ Please also consult our [guide](/docs/guides/manage/user/reg-create-user) on how ## Bulk import -For bulk import use the [import endpoint](https://zitadel.com/docs/apis/admin/admin-service-import-data) on the admin API: +For bulk import use the [import endpoint](https://zitadel.com/docs/apis/resources/admin/admin-service-import-data) on the admin API: ```json { @@ -220,7 +220,7 @@ Use metadata to store additional attributes of the users, such as organizational :::info Metadata must be added to users after the users were created. Currently metadata can't be added during user creation. -[API reference: User Metadata](https://zitadel.com/docs/category/apis/mgmt/user-metadata) +[API reference: User Metadata](https://zitadel.com/docs/category/apis/resources/mgmt/user-metadata) ::: Request metadata from the userinfo endpoint by passing the required [reserved scope](/docs/apis/openidoauth/scopes#reserved-scopes) in your auth request. @@ -232,5 +232,5 @@ You can assign roles from owned or granted projects to a user. :::info Authorizations must be added to users after the users were created. Currently metadata can't be added during user creation. -[API reference: User Authorization / Grants](https://zitadel.com/docs/category/apis/auth/user-authorizations-grants) +[API reference: User Authorization / Grants](https://zitadel.com/docs/category/apis/resources/auth/user-authorizations-grants) ::: \ No newline at end of file diff --git a/docs/docs/guides/overview.mdx b/docs/docs/guides/overview.mdx index 18bb541cac..7e9ae5a44b 100644 --- a/docs/docs/guides/overview.mdx +++ b/docs/docs/guides/overview.mdx @@ -1,49 +1,46 @@ --- -title: Overview +title: Documentation +sidebar_label: Overview --- -Most applications need to know the identity of a user for access control, to securely store their data in the cloud, and provide the same personalized experience across all of the user's devices. +Most applications require user identity for access control, secure data storage in the cloud, and to provide a consistent, personalized experience across all of a user's devices. +With ZITADEL, you can rely on a hardened and extensible turnkey solution to address all your authentication and authorization needs. We offer a wide range of features out of the box to accelerate your project. These features include multi-tenancy with branding customization, secure login, self-service, OpenID Connect, OAuth2.x, SAML2, Passwordless with FIDO2 (including Passkeys), OTP, U2F, and an unlimited audit trail. Execute custom code on selected events within ZITADEL to ensure compatibility with your unique and complex software landscape and data models. -With ZITADEL you can rely on a hardened and extensible turnkey solution to solve all of your authentication and authorization needs. -We provide you with a wide range of out of the box features to accelerate your project. Multi-tenancy with branding customization, secure login, self-service, OpenID Connect, OAuth2.x, SAML2, Passwordless with FIDO2 (including Passkeys), OTP, U2F, and an unlimited audit trail is there for you, ready to use. -Execute custom code on selected events within ZITADEL to ensure perfect compatibility with your unique and complex software landscape and data models. +## Get started -## Get Started +### Quick start guide -### Quick Start Guide +Follow our [quick start guide](/guides/start/quickstart). -Follow our [Quick Start Guide](/guides/start/quickstart). +### Cloud or self-hosting -### Cloud or Self-Hosting +You can use ZITADEL in two ways: -ZITADEL can be used in two ways: +- ZITADEL Cloud: This is our public cloud service. Use the free tier to start in minutes. +- Self-hosted ZITADEL: For full control, deploy ZITADEL wherever you prefer. -- Use the ZITADEL Cloud, our public cloud service. Use the free tier to get started in minutes. -- Deploy a self-hosted ZITADEL for full control, wherever you like. - -If you are unsure, opt for the gracious free tier of [ZITADEL Cloud](./manage/cloud/overview). +If you're unsure, consider the generous free tier of [ZITADEL Cloud](./manage/cloud/overview). Choose [ZITADEL Cloud](./manage/cloud/overview) if you want: -- A turnkey solution that just works -- A gracious free tier with a great pay-as-you-go option -- Global scalability without the headache of running it yourself +- A turnkey solution that's ready to go- A generous free tier with an excellent pay-as-you-go option +- Global scalability without the hassle of managing it yourself - Data-residency compliance for your customers -Choose [ZITADEL Self-Hosted](/self-hosting/deploy/overview) if you want: +Choose [ZITADEL self-hosted](/self-hosting/deploy/overview) if you want: - Total control over all components and your data - To run ZITADEL in air-gapped or regulated environments -- Flexibility when you deploy updates +- Flexibility when deploying updates -## Get Help +## Get help -Join our [Discord Chat](https://zitadel.com/chat) or open a [Discussion](https://github.com/zitadel/zitadel/discussions) on Github to get help from the community and the team behind ZITADEL. +Join our [Discord chat](https://zitadel.com/chat) or open a [discussion](https://github.com/zitadel/zitadel/discussions) on Github to get help from the community and the ZITADEL team. -Cloud and Enterprise customers can additionally reach us privately via the [Support communication channels](/legal/support-services). +Cloud and enterprise customers can additionally reach us privately via our [support communication channels](/legal/support-services). ## Contribute ZITADEL is open source — and so is the documentation. -Should you happen to stumble over an incorrectness, a spelling mistake, a hard-to-understand text passage, please don’t hesitate to leave a comment or [contribute a corresponding change](https://github.com/zitadel/zitadel/blob/main/CONTRIBUTING.md). +If you find any inaccuracies, spelling mistakes, or unclear text passages, please don't hesitate to leave a comment or [contribute a corresponding change](https://github.com/zitadel/zitadel/blob/main/CONTRIBUTING.md). \ No newline at end of file diff --git a/docs/docs/guides/solution-scenarios/b2c.mdx b/docs/docs/guides/solution-scenarios/b2c.mdx index afe027db6b..9ef542f93a 100644 --- a/docs/docs/guides/solution-scenarios/b2c.mdx +++ b/docs/docs/guides/solution-scenarios/b2c.mdx @@ -29,7 +29,7 @@ You can read more about how ZITADEL handles usernames [here](../manage/console/o ZITADEL gives you a basic storage for users and manages phone and email addresses. It also allows you to store your own application data such as preferences or external identifiers to the metadata of a user. If you are migrating an existing project and you already have an external identity store you can consider bulk importing your user datasets. -Read our [Management API definitions](/apis/mgmt) for more info. If the users email is not verified or no password is set, a initialization mail will be send. +Read our [Management API definitions](/apis/resources/mgmt) for more info. If the users email is not verified or no password is set, a initialization mail will be send. :::info Requests to the management API are rate limited. Read our [Rate limit Policy](../../legal/rate-limit-policy) for more info. diff --git a/docs/docs/guides/start/quickstart.mdx b/docs/docs/guides/start/quickstart.mdx index 18a9563c3f..e3d680cacc 100644 --- a/docs/docs/guides/start/quickstart.mdx +++ b/docs/docs/guides/start/quickstart.mdx @@ -1,5 +1,5 @@ --- -title: Quick Start Guide +title: Quick start guide --- import VSCodeFolderView from "../../../static/img/guides/quickstart/vscode1.png"; @@ -12,7 +12,7 @@ In this quick start guide, we will be learning some fundamentals on how to set u The sample application allows users to securely log in to ZITADEL using the OIDC Proof Key for Code Exchange (PKCE) flow. This flow ensures that the authentication process is secure by using a code verifier and a code challenge, which are sent to ZITADEL to obtain an access token. The access token is then used by the app to access the userinfo endpoint to retrieve and display information about the logged-in user. The app also has a logout feature that allows users to end their session and clear their access token. Overall, the app provides a simple and secure way for users to authenticate and access protected resources within ZITADEL. -## ZITADEL Terminology: Instances, Organizations, Projects, Users, Roles, Authorizations and Apps +## ZITADEL terminology: instances, organizations, projects, users, roles, authorizations and apps In ZITADEL, instances, organizations, projects, users, roles, and apps are the main components that make up the platform. @@ -31,9 +31,9 @@ The order of creation for the above components would typically be as follows: The order of creation for the above components may vary depending on the specific needs and requirements of the organization. -## Set Up and Manage ZITADEL for your Identity Projects +## Set up and manage ZITADEL for your identity projects -### 1. Sign up for the ZITADEL Cloud Customer Portal and Register your Organization +### 1. Sign up for the ZITADEL Cloud customer portal and register your organization 1. Go to [zitadel.com](http://zitadel.com) and click on “Start for FREE”. @@ -75,7 +75,7 @@ The order of creation for the above components may vary depending on the specifi ![Create Instance](/img/guides/quickstart/10.png) -### 2. Create your First Instance +### 2. Create your first instance As a user of the ZITADEL Cloud Customer Portal, you now can create multiple instances to suit your specific needs. This includes instances for development, production, or user acceptance testing, as well as instances for different clients or applications. For example, you might create an instance for each product in a B2C scenario, or an instance for each tenant or customer in a B2B scenario. The possibilities are endless. You can create a pay-as-you-go instance for production purposes. @@ -111,7 +111,7 @@ As a user of the ZITADEL Cloud Customer Portal, you now can create multiple inst ![Access Instance](/img/guides/quickstart/v2_7.png) -### 3. Create your First Project +### 3. Create your first project 1. To create a project in the instance you just created, click on “Create Project”. @@ -125,7 +125,7 @@ As a user of the ZITADEL Cloud Customer Portal, you now can create multiple inst ![Project Created](/img/guides/quickstart/21.png) -### 4. Add Users (optional) +### 4. Add users (optional) [Skip optional steps](quickstart/#7-create-an-application-in-your-project) and jump directly to the create application step. @@ -145,7 +145,7 @@ As a user of the ZITADEL Cloud Customer Portal, you now can create multiple inst ![User Info](/img/guides/quickstart/29.png) -### 5. Add Roles to your Project (optional) +### 5. Add roles to your project (optional) 1. To add roles to your project, click on “Roles” on the left as shown below. Next, click on the “New” button. @@ -163,7 +163,7 @@ As a user of the ZITADEL Cloud Customer Portal, you now can create multiple inst ![Add Role](/img/guides/quickstart/25.png) -### 6. Add Authorizations to your Project +### 6. Add authorizations to your project 1. Click on “Authorizations” on the top menu. @@ -193,7 +193,7 @@ As a user of the ZITADEL Cloud Customer Portal, you now can create multiple inst ![Add Authorization](/img/guides/quickstart/37.png) -### 7. Create an Application in your Project +### 7. Create an application in your project We will now create an application in the project, which will allow our React client application to access protected resources through the use of the OpenID Connect (OIDC) protocol. @@ -241,7 +241,7 @@ We will now create an application in the project, which will allow our React cli ![Add Application](/img/guides/quickstart/50.png) -### 8. Obtaining ClientId and OIDC Endpoints for your Application {#referred1} +### 8. Obtain ClientId and OIDC endpoints for your application {#referred1} You will need the ClientId and the OIDC endpoints (issuer and userinfo) when building your React application. The issuer URL is the base URL for the OIDC provider and includes the path to the OIDC discovery document, which contains information about the OIDC provider, including the authorization and token endpoints. By providing the issuer URL, you can use the OIDC library to automatically determine the endpoints for these requests. The authorization endpoint is used to initiate the authorization process, the token endpoint is used to exchange authorization codes for access tokens, and the userinfo endpoint is used to retrieve information about the user. You need an access token to access the userinfo endpoint and other protected resources. @@ -256,9 +256,9 @@ The authorization endpoint is used to initiate the authorization process, the to And with that, configuring ZITADEL for our application is complete. Now we can move on to building our React application. Let's get coding! -## Create Your React Application with ZITADEL OIDC PKCE Authentication +## Create your React application with ZITADEL OIDC PKCE authentication -### 1. Functional Requirements of the Application +### 1. Functional requirements of the application 1. The user navigates to the React app (client) and clicks the "login" button. 2. The app initiates the authorization process by redirecting the user’s browser to the authorization endpoint of the ZITADEL instance, along with the PKCE parameters (code challenge, and code challenge method). @@ -298,7 +298,7 @@ To install Visual Studio Code, go to their [website](https://code.visualstudio.c ### 3. Development -#### 1. Create Project +#### 1. Create project 1. Open a new terminal window in Visual Studio Code. 2. Navigate to the folder where you want to create the React app. 3. Run the following command to create a new React app named "react-oidc-zitadel": @@ -318,7 +318,7 @@ This will create the following files in your project: ``` npm install react-router-dom oidc-client-ts ``` -#### 2. Add Source Files +#### 2. Add source files The code needed to run this project can be found [here](https://github.com/zitadel/react-user-authentication). @@ -595,7 +595,7 @@ root.render( reportWebVitals(); ``` -### 4. Running the Application +### 4. Running the application 1. Run ```npm start``` to start the development server. 2. Open your browser and navigate to ```http://localhost:3000/``` to view the app. diff --git a/docs/docs/legal/introduction.mdx b/docs/docs/legal/introduction.mdx deleted file mode 100644 index 00bebc4a6a..0000000000 --- a/docs/docs/legal/introduction.mdx +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: Overview ---- - -import {ListElement, ListWrapper, ICONTYPE} from '../../src/components/list'; -import Column from '../../src/components/column'; - -This section contains important agreements, policies and appendices relevant for users of our websites and services. - -All documents will be provided in English language. - - - - - - - - - - - - - - - - - diff --git a/docs/docs/legal/terms-of-service-dedicated.md b/docs/docs/legal/terms-of-service-dedicated.md deleted file mode 100644 index d2bae23355..0000000000 --- a/docs/docs/legal/terms-of-service-dedicated.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: Dedicated Instance Terms -custom_edit_url: null ---- -## General - -Last revised: June 3, 2022 - -### Background - -Within the scope of the Framework Agreement, the Customer may choose to purchase a subscription that requires a dedicated instance of ZITADEL. These additional terms for dedicated instance ("**Dedicated Instance Terms**") apply in addition to the Framework Agreement. - -### Service - -CAOS operates and manages a **Dedicated Instance** of ZITADEL in a private infrastructure environment dedicated for the Customer and provides support services for the Customer according the Purchase Order, these terms, agreed [**Service Level Description**](service-level-description), and [**Support Service Descriptions**](support-services). - -Each Dedicated Instance consists, except agreed otherwise in writing, of a multi-zonal high-availability configuration that guarantees loads up to the specified [rate limits](rate-limit-policy#what-rate-limits-do-apply). - -### Operations - -CAOS will install and manage the Dedicated Instance on infracstructure provided by preferred cloud providers. Costs for infrastructure or cloud providers are not included in the Subscription, if not agreed otherwise in writing. - -You may choose to provide the required infrastructure yourself. You must comply with the requirements and prerequisites outlined in the purchase order. - -You may not modify, maintain or attempt to modify the Dedicated Instance, except with prior instructions by CAOS. - -CAOS will use the same backup strategy as for ZITADEL Cloud (public cloud) services, except otherwise agreed between you and CAOS in writing. - -### Maintenance and Updates - -We will access, modify, and maintain the Dedicated Instance at times solely determined by CAOS (**"Regular Maintenance"**). - -Under certain subscription plans, the Customer may agree a custom frequency and times for changes and updates. CAOS will coordinate the cadence and the changes with the Customer. To guarantee the quality of service, maintenance will occur on regular basis, typically monthly or sooner for security or performance related patches (**"Emergency Maintenance"**), but no longer than on quarterly basis. - -If you fail to permit CAOS to conduct Regular Maintenance for 3 consecutive months or Emergency Maintenance within 5 days of notification, then CAOS will raise this issue with the Customer via Escalation Process. In case the issue is not resolved 5 days after such an escalation, CAOS may terminate the subscription with 30 days prior written notice to Customer. CAOS is not obligated to provide the service according to the terms and SLA, nor is CAOS liable to any security breach or damages after failure to permit Regular Maintenance for 3 consecutive months, or Emergency Maintenance for 5 days after notification. - -### Incidents - -Incidents are handled as documented in the [**Support Service Descriptions**](support-services). If the Customer choose in Purchase Order to provide the required infrastructure, then any incidents related to the infrastructure of the Dedicated Instance have to be resolved through the Customer directly. diff --git a/docs/docs/legal/terms-of-service.md b/docs/docs/legal/terms-of-service.md index ee2b8be36d..e963ae58d2 100644 --- a/docs/docs/legal/terms-of-service.md +++ b/docs/docs/legal/terms-of-service.md @@ -25,10 +25,6 @@ The following policies complement the TOS. When accepting the TOS, you accept th * [**Acceptable Use Policy**](acceptable-use-policy) - What we understand as acceptable and fair use of our Services * [**Rate Limit Policy**](rate-limit-policy) - How we avoid overloads of our services -This Agreement is extended with additional terms, in case your Subscription requires a Dedicated Instance. When you enter the Agreement with us, you accept these additional agreements. - -* [**Dedicated Instance Terms**](terms-of-service-dedicated) - How we provide our services for a dedicated instance - ### Alterations Any provisions which deviate from these TOS must be agreed in writing between the Customer and us. Such agreements shall take precedence over the TOS outlined in this document. @@ -195,7 +191,7 @@ Should any provision of these TOS be or become invalid, this shall not affect th These TOS shall enter into force as of 15.07.2022. -Last revised: June 14, 2022 +Last revised: May 12, 2023 ### Amendments diff --git a/docs/docs/sdks/introduction.mdx b/docs/docs/sdks/introduction.mdx deleted file mode 100644 index 96825dfa46..0000000000 --- a/docs/docs/sdks/introduction.mdx +++ /dev/null @@ -1,133 +0,0 @@ ---- -title: Overview ---- - -import Tabs from "@theme/Tabs"; -import TabItem from "@theme/TabItem"; -import { Card, CardWrapper } from "../../src/components/card"; - -Get started with ZITADEL quickly by reading a quickstart or by cloning a [ZITADEL example](https://github.com/search?q=topic%3Aexamples+org%3Azitadel) repo. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -## Clone a sample project - - - - - - - - - -## Libraries - -| Language | Description | Link | -| -------- | ------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | -| Go | Go client library for ZITADEL. | [https://github.com/zitadel/zitadel-go](https://github.com/zitadel/zitadel-go) | -| .Net | Authentication / Authorization library written in dotnet for the asp.net web application package. | [https://github.com/zitadel/zitadel-net](https://github.com/zitadel/zitadel-net) | -| Dart | Dart library for ZITADEL, contains gRPC and API access elements. | [https://github.com/zitadel/zitadel-dart](https://github.com/zitadel/zitadel-dart) | -| Elixir | API Client for the ZITADEL API. | [https://github.com/jshmrtn/zitadel_api](https://github.com/jshmrtn/zitadel_api) | diff --git a/docs/docs/self-hosting/deploy/overview.mdx b/docs/docs/self-hosting/deploy/overview.mdx index c9acfa57a1..8797c43594 100644 --- a/docs/docs/self-hosting/deploy/overview.mdx +++ b/docs/docs/self-hosting/deploy/overview.mdx @@ -1,5 +1,6 @@ --- -title: Overview +title: Deploy ZITADEL +sidebar_label: Overview --- Choose your platform and run ZITADEL with the most minimal configuration possible. @@ -13,7 +14,8 @@ Choose your platform and run ZITADEL with the most minimal configuration possibl ## Prerequisites - For test environments, ZITADEL does not need many resources, 1 CPU and 512MB memory are more than enough. (With more CPU, the password hashing might be faster) -- A cockroachDB or Postgresql (currently in beta) as only needed storage +- A CockroachDB or Postgresql as only needed storage. Make sure to read our [Production Guide](./self-hosting/manage/production#prefer-cockroachdb) before you decide to use Postgresql. +) ## Releases diff --git a/docs/docs/self-hosting/manage/database/_postgres.mdx b/docs/docs/self-hosting/manage/database/_postgres.mdx index 25e75f4c45..ace58ef328 100644 --- a/docs/docs/self-hosting/manage/database/_postgres.mdx +++ b/docs/docs/self-hosting/manage/database/_postgres.mdx @@ -1,10 +1,16 @@ ## Postgres :::caution -Postgres extension is currently in beta. +PostgreSQL extension is currently in [Beta](/docs/support/software-release-cycles-support#beta). +Beta state will be removed as soon as automated tests are implemented. [Github Issue](https://github.com/zitadel/zitadel/issues/5741) +::: + +:::caution +Be aware that PostgreSQL is only [Enterprise Supported](/docs/support/software-release-cycles-support#partially-supported). ::: If you want to use a PostgreSQL database instead of CockroachDB you can [overwrite the default configuration](../configure/configure.mdx). +Make sure to read our [Production Guide](./self-hosting/manage/production#prefer-cockroachdb) before you decide to use it. Currently versions >= 14 are supported. diff --git a/docs/docs/self-hosting/manage/production.md b/docs/docs/self-hosting/manage/production.md index 1bc926db2e..acdbb96888 100644 --- a/docs/docs/self-hosting/manage/production.md +++ b/docs/docs/self-hosting/manage/production.md @@ -71,6 +71,11 @@ as horizontal scaling is much easier than with PostgreSQL. Also, if you are concerned about multi-regional data locality, [the way to go is with CockroachDB](https://www.cockroachlabs.com/docs/stable/multiregion-overview.html). +The indexes for the database are optimized using load tests from [ZITADEL Cloud](https://zitadel.com), +which runs with CockroachDB. +If you identify problems with your Postgresql during load tests that indicate that the indexes are not optimized, +please create an issue in our [github repository](https://github.com/zitadel/zitadel). + ### Configure ZITADEL Depending on your environment, you maybe would want to tweak some settings about how ZITADEL interacts with the database in the database section of your ZITADEL configuration. Read more about your [database configuration options](/docs/self-hosting/manage/database). diff --git a/docs/docs/self-hosting/manage/quotas.md b/docs/docs/self-hosting/manage/quotas.md index 1d0d48702c..f20ad57245 100644 --- a/docs/docs/self-hosting/manage/quotas.md +++ b/docs/docs/self-hosting/manage/quotas.md @@ -6,7 +6,7 @@ Quotas is an enterprise feature that is relevant if you want to host ZITADEL as It enables you to limit usage and/or register webhooks that trigger on configurable usage levels for certain units. For example, you might want to report usage to an external billing tool and notify users when 80 percent of a quota is exhausted. Quotas are currently supported [for the instance level only](/concepts/structure/instance). -Please refer to the [system API docs](/apis/system) for detailed explanations about how to use the quotas feature. +Please refer to the [system API docs](/apis/resources/system) for detailed explanations about how to use the quotas feature. ZITADEL supports limiting authenticated requests and action run seconds diff --git a/docs/docs/support/software-release-cycles-support.md b/docs/docs/support/software-release-cycles-support.md new file mode 100644 index 0000000000..d193e30241 --- /dev/null +++ b/docs/docs/support/software-release-cycles-support.md @@ -0,0 +1,72 @@ +--- +title: Support States & Software Release Cycle +--- + +## Support States + +It's important to note that support may differ depending on the feature, and not all features may be fully supported. +We always strive to provide the best support possible for our customers and community, +but we may not be able to provide immediate or comprehensive support for all features. +Also the support may differ depending on your contracts. Read more about it on our [Legal page](/docs/legal) + +### Supported + +Supported features are those that are guaranteed to work as intended and are fully tested by our team. +If you encounter any issues with a supported feature, please contact us by creating a [bug report](https://github.com/zitadel/zitadel/issues/new/choose). +We will review the issues according to our [product management process](https://github.com/zitadel/zitadel/blob/main/CONTRIBUTING.md#product-management). + +In case you are eligible to [support services](/docs/legal/support-services) get in touch via one of our support channels and we will provide prompt response to the issues you may experience and make our best effort to assist you to find a resolution. + +:::info Security Issues +Please report any security issues immediately to the indicated address in our [security.txt](https://zitadel.com/.well-known/security.txt) +::: + +### Enterprise Supported + +Enterprise supported features are those where we provide support only to users eligible for enterprise [support services](/docs/legal/support-services). +These features should be functional for eligible users, but may have some limitations for a broader use. + +If you encounter issues with an enterprise supported feature and you are eligible for enterprise support services, we will provide a prompt response to the issues you may experience and make our best effort to assist you to find a resolution. + +**Enterprise supported features** + +- Database PostgreSQL +- LDAP Identity Provider +- [Terraform Provider](https://github.com/zitadel/terraform-provider-zitadel) + +### Community Supported + +Community supported features are those that have been developed by our community and may not have undergone extensive testing or support from our team. +If you encounter issues with a community supported feature, we encourage you to seek help from our community or other online resources, where other users can provide assistance: + +- Join our [Discord Chat](https://zitadel.com/chat) +- Search [Github Issues](https://github.com/search?q=org%3Azitadel+&type=issues) and report a new issue +- Search [Github Discussions](https://github.com/search?q=org%3Azitadel+&type=discussions) and open a new discussion as question or idea + +## Software Release Cycle + +It's important to note that both Alpha and Beta software can have breaking changes, meaning they are not backward-compatible with previous versions of the software. +Therefore, it's recommended to use caution when using Alpha and Beta software, and to always back up important data before installing or testing new software versions. + +Only features in General Availability will be covered by support services. + +We encourage our community to test Alpha and Beta software and provide feedback via our [Discord Chat](https://zitadel.com/chat). + +### Alpha + +The Alpha state is our initial testing phase. +It is available to everyone, but it is not yet complete and may contain bugs and incomplete features. +We recommend that users exercise caution when using Alpha software and avoid using it for critical tasks, as support is limited during this phase. + +### Beta + +The Beta state comes after the Alpha phase and is a more stable version of the software. +It is feature-complete, but may still contain bugs that need to be fixed before general availability. +While it is available to everyone, we recommend that users exercise caution when using Beta software and avoid using it for critical tasks. +During this phase, support is limited as we focus on testing and bug fixing. + +### General Available + +Generally available features are available to everyone and have the appropriate test coverage to be used for critical tasks. +The software will be backwards-compatible with previous versions, for exceptions we will publish a [technical advisory](https://zitadel.com/docs/support/technical_advisory). +Features in General Availability are not marked explicitly. diff --git a/docs/docs/support/trainings/introduction.md b/docs/docs/support/trainings/introduction.md index 2c3554366f..270d6e9061 100644 --- a/docs/docs/support/trainings/introduction.md +++ b/docs/docs/support/trainings/introduction.md @@ -1,5 +1,6 @@ --- -title: Introduction +title: Trainings +sidebar_label: Introduction --- The following pages describe the the trainings provided by ZITADEL. These trainings are intended for onboarding and during the course of a Support Program. diff --git a/docs/docs/support/troubleshooting.md b/docs/docs/support/troubleshooting.md index c70d8109e1..05e986fd43 100644 --- a/docs/docs/support/troubleshooting.md +++ b/docs/docs/support/troubleshooting.md @@ -8,8 +8,7 @@ You will find some possible error messages here, what the problem is and what so Join or [Chat](https://zitadel.com/chat) or open a [Discussion](https://github.com/zitadel/zitadel/discussions). ::: - -## User Agent does not correspond +## User agent does not correspond This error appeared for some users as soon as they were redirected to the login page of ZITADEL. ZITADEL uses some cookies to identify the browser/user agent of the user, so it is able to store the active user sessions. By blocking the cookies the functions of ZITADEL will be affected. @@ -34,6 +33,14 @@ Do you still face this issue? Please contact us, and we will help you find out w `ID=QUERY-n0wng Message=Instance not found` -If you're in an self-hosting scenario with a custom domain, you need to instruct ZITADEL to use the `ExternalDomain`. -You can find more instruction in our guide about [custom domains](https://zitadel.com/docs/self-hosting/manage/custom-domain). +If you're self hosting with a custom domain, you need to instruct ZITADEL to use the `ExternalDomain`. +You can find further instructions in our guide about [custom domains](https://zitadel.com/docs/self-hosting/manage/custom-domain). We also provide a guide on how to [configure](https://zitadel.com/docs/self-hosting/manage/configure) ZITADEL with variables from files or environment variables. + +## WebFinger requirement for Tailscale + +The WebFinger requirement and setup is a step a user has to take outside of their IdP set-up. WebFinger is a protocol which supports the ability for OIDC issuer discovery, and we use it to prove that the user has administrative control over the domain and to retrieve the issuer. This is a requirement we have in place for all users, regardless of their IdP, who use custom OIDC with Tailscale. + +On their custom domain, e.g example.com, users need to host a WebFinger endpoint at https://example.com/.well-known/webfinger. When queried, this endpoint returns a JSON response detailing the issuer. Users would need to host the endpoint with the link to the ZITADEL issuer. Tailscale only looks up this endpoint once when a user signs up, and will only look up this endpoint again if the user needs to make a configuration change to their identity provider. + +The requirements and a set up guide is detailed in the [Tailscale documentation](https://tailscale.com/kb/1240/sso-custom-oidc/). diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js index 409f3905e3..ccac55b08e 100644 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -83,7 +83,7 @@ module.exports = { }, { type: "doc", - docId: "legal/introduction", + docId: "legal", label: "Legal", position: "right", }, @@ -234,49 +234,49 @@ module.exports = { config: { auth: { specPath: ".artifacts/openapi/zitadel/auth.swagger.json", - outputDir: "docs/apis/auth", + outputDir: "docs/apis/resources/auth", sidebarOptions: { groupPathsBy: "tag", }, }, mgmt: { specPath: ".artifacts/openapi/zitadel/management.swagger.json", - outputDir: "docs/apis/mgmt", + outputDir: "docs/apis/resources/mgmt", sidebarOptions: { groupPathsBy: "tag", }, }, admin: { specPath: ".artifacts/openapi/zitadel/admin.swagger.json", - outputDir: "docs/apis/admin", + outputDir: "docs/apis/resources/admin", sidebarOptions: { groupPathsBy: "tag", }, }, system: { specPath: ".artifacts/openapi/zitadel/system.swagger.json", - outputDir: "docs/apis/system", + outputDir: "docs/apis/resources/system", sidebarOptions: { groupPathsBy: "tag", }, }, user: { specPath: ".artifacts/openapi/zitadel/user/v2alpha/user_service.swagger.json", - outputDir: "docs/apis/user_service", + outputDir: "docs/apis/resources/user_service", sidebarOptions: { groupPathsBy: "tag", }, }, session: { specPath: ".artifacts/openapi/zitadel/session/v2alpha/session_service.swagger.json", - outputDir: "docs/apis/session_service", + outputDir: "docs/apis/resources/session_service", sidebarOptions: { groupPathsBy: "tag", }, }, settings: { specPath: ".artifacts/openapi/zitadel/settings/v2alpha/settings_service.swagger.json", - outputDir: "docs/apis/settings_service", + outputDir: "docs/apis/resources/settings_service", sidebarOptions: { groupPathsBy: "tag", }, diff --git a/docs/nginx.conf b/docs/nginx.conf index 1af667f386..7b64550084 100644 --- a/docs/nginx.conf +++ b/docs/nginx.conf @@ -15,7 +15,7 @@ http { } location /docs { - root /usr/share/nginx/html; + alias /usr/share/nginx/html; index /docs/index.html; try_files $uri $uri/ /docs/index.html?q=$query_string; } @@ -23,7 +23,7 @@ http { location = /docs/proxy/js/script.js { proxy_pass https://plausible.io/js/script.js; proxy_set_header Host plausible.io; - } + } location = /docs/proxy/api/event { proxy_pass https://plausible.io/api/event; @@ -53,4 +53,4 @@ http { application/xml application/json application/ld+json; -} \ No newline at end of file +} diff --git a/docs/sidebars.js b/docs/sidebars.js index 54ca65bb18..3615dee280 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -33,7 +33,7 @@ module.exports = { "examples/sdks", { type: "category", - label: "Example Applications", + label: "Example applications", items: [ "examples/introduction", { @@ -57,8 +57,14 @@ module.exports = { { type: "category", label: "Cloud", + link: { + type: "generated-index", + title: "Overview", + slug: "guides/manage/cloud/overview", + description: + "Our customer portal is used to manage all your ZITADEL instances. You can also manage your subscriptions, billing, newsletters and support requests.", + }, items: [ - "guides/manage/cloud/overview", "guides/manage/cloud/start", "guides/manage/cloud/instances", "guides/manage/cloud/billing", @@ -136,7 +142,7 @@ module.exports = { items: [ { type: "category", - label: "Authenticate Users", + label: "Authenticate users", collapsed: true, items: [ "guides/integrate/login-users", @@ -146,7 +152,7 @@ module.exports = { }, { type: "category", - label: "Configure Identity Providers", + label: "Configure identity providers", link: { type: "generated-index", title: "Let users login with their preferred identity provider", @@ -174,7 +180,7 @@ module.exports = { items: [ { type: "category", - label: "Authenticate Service Users", + label: "Authenticate service users", link: { type: "generated-index", title: "Authenticate Service Users", @@ -194,7 +200,7 @@ module.exports = { "guides/integrate/event-api", { type: "category", - label: "Example Code", + label: "Example code", items: [ "examples/call-zitadel-api/go", "examples/call-zitadel-api/dot-net", @@ -247,13 +253,13 @@ module.exports = { }, { type: "category", - label: "Solution Scenarios", + label: "Solution scenarios", link: { type: "generated-index", - title: "Solution Scenarios", + title: "Solution scenarios", slug: "guides/solution-scenarios/introduction", description: - "Customers of an SaaS Identity and Access Management System usually have all distinct use cases and requirements. This guide attempts to explain real-world implementations and break them down into Solution Scenarios which aim to help you getting started with ZITADEL.", + "Customers of an SaaS Identity and access management system usually have all distinct use cases and requirements. This guide attempts to explain real-world implementations and break them down into solution scenarios which aim to help you getting started with ZITADEL.", }, collapsed: true, items: [ @@ -268,8 +274,14 @@ module.exports = { type: "category", label: "Concepts", collapsed: true, + link: { + type: "generated-index", + title: "Concepts and Features", + slug: "concepts", + description: + "This part of our documentation contains ZITADEL specific or general concepts required to understand the system or our guides.", + }, items: [ - "concepts/introduction", "concepts/structure/instance", "concepts/structure/organizations", "concepts/structure/projects", @@ -310,10 +322,11 @@ module.exports = { label: "Support", collapsed: true, items: [ + "support/software-release-cycles-support", "support/troubleshooting", { type: 'category', - label: "Technical Advisory", + label: "Technical advisory", link: { type: 'doc', id: 'support/technical_advisory', @@ -349,96 +362,96 @@ module.exports = { items: [ { type: "category", - label: "Authenticated User", + label: "Authenticated user", link: { type: "generated-index", title: "Auth API", - slug: "/apis/auth", + slug: "/apis/resources/auth", description: "The authentication API (aka Auth API) is used for all operations on the currently logged in user. The user id is taken from the sub claim in the token.", }, - items: require("./docs/apis/auth/sidebar.js"), + items: require("./docs/apis/resources/auth/sidebar.js"), }, { type: "category", - label: "Organization Objects", + label: "Organization objects", link: { type: "generated-index", title: "Management API", - slug: "/apis/mgmt", + slug: "/apis/resources/mgmt", description: "The management API is as the name states the interface where systems can mutate IAM objects like, organizations, projects, clients, users and so on if they have the necessary access rights. To identify the current organization you can send a header x-zitadel-orgid or if no header is set, the organization of the authenticated user is set.", }, - items: require("./docs/apis/mgmt/sidebar.js"), + items: require("./docs/apis/resources/mgmt/sidebar.js"), }, { type: "category", - label: "Instance Objects", + label: "Instance objects", link: { type: "generated-index", title: "Admin API", - slug: "/apis/admin", + slug: "/apis/resources/admin", description: "This API is intended to configure and manage one ZITADEL instance itself.", }, - items: require("./docs/apis/admin/sidebar.js"), + items: require("./docs/apis/resources/admin/sidebar.js"), }, { type: "category", - label: "Instance Lifecycle", + label: "Instance lifecycle", link: { type: "generated-index", title: "System API", - slug: "/apis/system", + slug: "/apis/resources/system", description: "This API is intended to manage the different ZITADEL instances within the system.\n" + "\n" + "Checkout the guide how to access the ZITADEL System API.", }, - items: require("./docs/apis/system/sidebar.js"), + items: require("./docs/apis/resources/system/sidebar.js"), }, { type: "category", - label: "User Lifecycle (Alpha)", + label: "User lifecycle (alpha)", link: { type: "generated-index", - title: "User Service API (Alpha)", - slug: "/apis/user_service", + title: "User service API (Alpha)", + slug: "/apis/resources/user_service", description: "This API is intended to manage users in a ZITADEL instance.\n"+ "\n"+ "This project is in alpha state. It can AND will continue breaking until the services provide the same functionality as the current login.", }, - items: require("./docs/apis/user_service/sidebar.js"), + items: require("./docs/apis/resources/user_service/sidebar.js"), }, { type: "category", - label: "Session Lifecycle (Alpha)", + label: "Session lifecycle (Alpha)", link: { type: "generated-index", - title: "Session Service API (Alpha)", - slug: "/apis/session_service", + title: "Session service API (Alpha)", + slug: "/apis/resources/session_service", description: "This API is intended to manage sessions in a ZITADEL instance.\n"+ "\n"+ "This project is in alpha state. It can AND will continue breaking until the services provide the same functionality as the current login.", }, - items: require("./docs/apis/session_service/sidebar.js"), + items: require("./docs/apis/resources/session_service/sidebar.js"), }, { type: "category", - label: "Settings Lifecycle (Alpha)", + label: "Settings lifecycle (alpha)", link: { type: "generated-index", - title: "Settings Service API (Alpha)", - slug: "/apis/settings_service", + title: "Settings service API (Alpha)", + slug: "/apis/resources/settings_service", description: "This API is intended to manage settings in a ZITADEL instance.\n"+ "\n"+ - "This project is in alpha state. It can AND will continue breaking until the services provide the same functionality as the current login.", + "This project is in alpha state. It can AND will continue to break until the services provide the same functionality as the current login.", }, - items: require("./docs/apis/settings_service/sidebar.js"), + items: require("./docs/apis/resources/settings_service/sidebar.js"), }, { type: "category", @@ -489,7 +502,7 @@ module.exports = { }, { type: "doc", - label: "gRPC Status Codes", + label: "gRPC status codes", id: "apis/statuscodes" }, { @@ -500,7 +513,7 @@ module.exports = { }, { type: 'link', - label: 'Rate Limits (Cloud)', // The link label + label: 'Rate limits (cloud)', // The link label href: '/legal/rate-limit-policy', // The internal path }, ], @@ -537,41 +550,51 @@ module.exports = { ], }, ], - support: [ - ], legal: [ - "legal/introduction", - "legal/terms-of-service", - "legal/data-processing-agreement", { type: "category", - label: "Service Description", + label: "Legal agreements", collapsed: false, + link: { + type: "generated-index", + title: "Legal agreements", + slug: "legal", + description: + "This section contains important agreements, policies and appendices relevant for users of our websites and services. All documents will be provided in English language.", + }, items: [ - "legal/cloud-service-description", - "legal/service-level-description", - "legal/support-services", - ], - }, - { - type: "category", - label: "Additional terms", - collapsed: true, - items: [ - "legal/terms-support-service", - "legal/terms-of-service-dedicated", - ], - }, - { - type: "category", - label: "Policies", - collapsed: false, - items: [ - "legal/privacy-policy", - "legal/acceptable-use-policy", - "legal/rate-limit-policy", - "legal/vulnerability-disclosure-policy", - ], + "legal/terms-of-service", + "legal/data-processing-agreement", + { + type: "category", + label: "Service description", + collapsed: false, + items: [ + "legal/cloud-service-description", + "legal/service-level-description", + "legal/support-services", + ], + }, + { + type: "category", + label: "Support program", + collapsed: true, + items: [ + "legal/terms-support-service", + ], + }, + { + type: "category", + label: "Policies", + collapsed: false, + items: [ + "legal/privacy-policy", + "legal/acceptable-use-policy", + "legal/rate-limit-policy", + "legal/vulnerability-disclosure-policy", + ], + }, + ] }, ], }; diff --git a/docs/src/pages/index.js b/docs/src/pages/index.js index 727c29eac9..544f43cbb2 100644 --- a/docs/src/pages/index.js +++ b/docs/src/pages/index.js @@ -154,19 +154,19 @@ const features = [
{ }); }); - it('authenticated requests are limited', () => { + it('only authenticated requests are limited', () => { cy.get>('@authenticatedUrls').then((urls) => { cy.get('@ctx').then((ctx) => { const start = new Date(); @@ -109,9 +109,9 @@ describe('quotas', () => { }); expectCookieDoesntExist(); const expiresMax = new Date(); - expiresMax.setMinutes(expiresMax.getMinutes() + 2); + expiresMax.setMinutes(expiresMax.getMinutes() + 20); cy.request({ - url: urls[0], + url: urls[1], method: 'GET', auth: { bearer: ctx.api.token, @@ -129,7 +129,19 @@ describe('quotas', () => { createHumanUser(ctx.api, testUserName, false).then((res) => { expect(res.status).to.equal(429); }); + // visit limited console + cy.visit('/users/me'); + cy.contains('#authenticated-requests-exhausted-dialog button', 'Continue').click(); + const upgradeInstancePage = `https://example.com/instances/${ctx.instanceId}`; + cy.origin(upgradeInstancePage, { args: { upgradeInstancePage } }, ({ upgradeInstancePage }) => { + cy.location('href').should('equal', upgradeInstancePage); + }); + // upgrade instance ensureQuotaIsRemoved(ctx, Unit.AuthenticatedRequests); + // visit upgraded console again + cy.visit('/users/me'); + cy.get('[data-e2e="top-view-title"]'); + expectCookieDoesntExist(); createHumanUser(ctx.api, testUserName); expectCookieDoesntExist(); }); diff --git a/e2e/package.json b/e2e/package.json index 3490c1e35f..45ae558b54 100644 --- a/e2e/package.json +++ b/e2e/package.json @@ -8,6 +8,8 @@ "e2e:golang": "npm run e2e --", "open:golangangular": "CYPRESS_BASE_URL=http://localhost:4200 CYPRESS_BACKEND_URL=http://localhost:8080 npm run open --", "e2e:golangangular": "CYPRESS_BASE_URL=http://localhost:4200 CYPRESS_BACKEND_URL=http://localhost:8080 npm run e2e --", + "open:angulargolang": "npm run open:golangangular --", + "e2e:angulargolang": "npm run e2e:golangangular --", "open:angular": "CYPRESS_BASE_URL=http://localhost:4200 CYPRESS_BACKEND_URL=http://localhost:8080 CYPRESS_WEBHOOK_HANDLER_HOST=host.docker.internal npm run open --", "e2e:angular": "CYPRESS_BASE_URL=http://localhost:4200 CYPRESS_BACKEND_URL=http://localhost:8080 CYPRESS_WEBHOOK_HANDLER_HOST=host.docker.internal npm run e2e --", "lint": "prettier --check cypress", diff --git a/go.mod b/go.mod index 24774459bf..eeca72a61d 100644 --- a/go.mod +++ b/go.mod @@ -15,12 +15,13 @@ require ( github.com/benbjohnson/clock v1.3.0 github.com/boombuler/barcode v1.0.1 github.com/cockroachdb/cockroach-go/v2 v2.3.3 + github.com/descope/virtualwebauthn v1.0.2 github.com/dop251/goja v0.0.0-20230402114112-623f9dda9079 github.com/dop251/goja_nodejs v0.0.0-20230322100729-2550c7b6c124 github.com/drone/envsubst v1.0.3 - github.com/duo-labs/webauthn v0.0.0-20221205164246-ebaf9b74c6ec github.com/envoyproxy/protoc-gen-validate v0.10.1 github.com/go-ldap/ldap/v3 v3.4.4 + github.com/go-webauthn/webauthn v0.8.2 github.com/golang/glog v1.1.1 github.com/golang/mock v1.6.0 github.com/golang/protobuf v1.5.3 @@ -50,15 +51,15 @@ require ( github.com/pkg/errors v0.9.1 github.com/pquerna/otp v1.4.0 github.com/rakyll/statik v0.1.7 - github.com/rs/cors v1.8.3 + github.com/rs/cors v1.9.0 github.com/sony/sonyflake v1.1.0 github.com/spf13/cobra v1.7.0 github.com/spf13/viper v1.15.0 - github.com/stretchr/testify v1.8.2 + github.com/stretchr/testify v1.8.3 github.com/superseriousbusiness/exifremove v0.0.0-20210330092427-6acd27eac203 github.com/ttacon/libphonenumber v1.2.1 github.com/zitadel/logging v0.3.4 - github.com/zitadel/oidc/v2 v2.4.0 + github.com/zitadel/oidc/v2 v2.6.1 github.com/zitadel/saml v0.0.11 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.40.0 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.40.0 @@ -70,9 +71,9 @@ require ( go.opentelemetry.io/otel/sdk v1.14.0 go.opentelemetry.io/otel/sdk/metric v0.37.0 go.opentelemetry.io/otel/trace v1.14.0 - golang.org/x/crypto v0.7.0 - golang.org/x/net v0.9.0 - golang.org/x/oauth2 v0.7.0 + golang.org/x/crypto v0.9.0 + golang.org/x/net v0.10.0 + golang.org/x/oauth2 v0.8.0 golang.org/x/sync v0.1.0 golang.org/x/text v0.9.0 golang.org/x/tools v0.7.0 @@ -86,12 +87,16 @@ require ( require ( github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.37.0 // indirect - github.com/cloudflare/cfssl v1.6.3 // indirect github.com/go-logr/logr v1.2.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-sql-driver/mysql v1.6.0 // indirect + github.com/go-webauthn/revoke v0.1.9 // indirect + github.com/google/go-tpm v0.3.3 // indirect github.com/google/pprof v0.0.0-20230323073829-e72429f035bd // indirect + github.com/gorilla/websocket v1.4.2 // indirect github.com/klauspost/cpuid/v2 v2.2.4 // indirect github.com/pelletier/go-toml/v2 v2.0.7 // indirect + github.com/smartystreets/assertions v1.0.0 // indirect go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.14.0 // indirect go.uber.org/multierr v1.11.0 // indirect ) @@ -136,7 +141,6 @@ require ( github.com/golang/geo v0.0.0-20230404232722-c4acd7a044dc // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/snappy v0.0.4 // indirect - github.com/google/certificate-transparency-go v1.1.4 // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/google/uuid v1.3.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect @@ -179,7 +183,7 @@ require ( github.com/prometheus/procfs v0.9.0 // indirect github.com/rs/xid v1.4.0 // indirect github.com/russellhaering/goxmldsig v1.3.0 // indirect - github.com/sirupsen/logrus v1.9.0 + github.com/sirupsen/logrus v1.9.2 github.com/spf13/afero v1.9.5 // indirect github.com/spf13/cast v1.5.0 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect @@ -192,7 +196,7 @@ require ( go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.14.0 // indirect go.opentelemetry.io/proto/otlp v0.19.0 // indirect golang.org/x/mod v0.10.0 // indirect - golang.org/x/sys v0.7.0 + golang.org/x/sys v0.8.0 golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/appengine v1.6.7 // indirect gopkg.in/ini.v1 v1.67.0 // indirect diff --git a/go.sum b/go.sum index 382d482406..716d80a780 100644 --- a/go.sum +++ b/go.sum @@ -1,10 +1,6 @@ -bazil.org/fuse v0.0.0-20180421153158-65cc252bf669/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= -bitbucket.org/creachadair/shell v0.0.6/go.mod h1:8Qqi/cYk7vPnsOePHroKXDJYmb5x7ENhtiFtfZq8K+M= -bitbucket.org/liamstask/goose v0.0.0-20150115234039-8488cc47d90c/go.mod h1:hSVuE3qU7grINVSwrmzHfpg9k87ALBk+XaualNyUzI4= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.39.0/go.mod h1:rVLT6fkc8chs9sfPtFc1SBH6em7n+ZoXaG+87tDISts= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= @@ -21,9 +17,6 @@ cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHOb cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= -cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= -cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= -cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= cloud.google.com/go v0.110.0 h1:Zc8gqp3+a9/Eyph2KDmcGaPtbKRIoqq4YTlL4NMD0Ys= cloud.google.com/go v0.110.0/go.mod h1:SJnCLqQ0FCFGSZMUNUf84MV3Aia54kn7pi8st7tMzaY= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= @@ -38,7 +31,6 @@ cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGB cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= cloud.google.com/go/iam v1.0.0 h1:hlQJMovyJJwYjZcTohUH4o1L8Z8kYz+E+W/zktiLCBc= cloud.google.com/go/iam v1.0.0/go.mod h1:ikbQ4f1r91wTmBmmOtBCOtuEOei6taatNXytzB7Cxew= cloud.google.com/go/logging v1.7.0 h1:CJYxlNNNNAMkHp9em/YEXcfJg+rPDg7YfwoRpMU+t5I= @@ -48,7 +40,6 @@ cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2k cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/spanner v1.17.0/go.mod h1:+17t2ixFwRG4lWRwE+5kipDR9Ef07Jkmc8z0IbMDKUs= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= @@ -59,21 +50,7 @@ cloud.google.com/go/storage v1.30.1 h1:uOdMxAs8HExqBlnLtnQyP0YkvbiDpdGShGKtx6U/o cloud.google.com/go/storage v1.30.1/go.mod h1:NfxhC0UJE1aXSx7CIIbCf7y9HKT7BiccwkR7+P7gN8E= cloud.google.com/go/trace v1.9.0 h1:olxC0QHC59zgJVALtgqfD9tGk0lfeCP5/AGXL3Px/no= cloud.google.com/go/trace v1.9.0/go.mod h1:lOQqpE5IaWY0Ixg7/r2SjixMuc6lfTFeO4QGM4dQWOk= -code.gitea.io/sdk/gitea v0.11.3/go.mod h1:z3uwDV/b9Ls47NGukYM9XhnHtqPh/J+t40lsUrR6JDY= -contrib.go.opencensus.io/exporter/aws v0.0.0-20181029163544-2befc13012d0/go.mod h1:uu1P0UCM/6RbsMrgPa98ll8ZcHM858i/AD06a9aLRCA= -contrib.go.opencensus.io/exporter/ocagent v0.5.0/go.mod h1:ImxhfLRpxoYiSq891pBrLVhN+qmP8BTVvdH2YLs7Gl0= -contrib.go.opencensus.io/exporter/stackdriver v0.12.1/go.mod h1:iwB6wGarfphGGe/e5CWqyUk/cLzKnWsOKPVW3no6OTw= -contrib.go.opencensus.io/exporter/stackdriver v0.13.5/go.mod h1:aXENhDJ1Y4lIg4EUaVTwzvYETVNZk10Pu26tevFKLUc= -contrib.go.opencensus.io/integrations/ocsql v0.1.4/go.mod h1:8DsSdjz3F+APR+0z0WkU1aRorQCFfRxvqjUUPMbF3fE= -contrib.go.opencensus.io/resource v0.1.1/go.mod h1:F361eGI91LCmW1I/Saf+rX0+OFcigGlFvXwEGEnkRLA= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/Azure/azure-amqp-common-go/v2 v2.1.0/go.mod h1:R8rea+gJRuJR6QxTir/XuEd+YuKoUiazDC/N96FiDEU= -github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4= -github.com/Azure/azure-sdk-for-go v29.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-sdk-for-go v30.1.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-service-bus-go v0.9.1/go.mod h1:yzBx6/BUGfjfeqbRZny9AQIbIe3AcV9WZbAdpkoXOa0= -github.com/Azure/azure-storage-blob-go v0.8.0/go.mod h1:lPI3aLPpuLTeUwh1sViKXFxwl2B6teiRqI0deQUvsw0= -github.com/Azure/go-autorest v12.0.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-ntlmssp v0.0.0-20220621081337-cb9428e4ac1e/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 h1:mFRzDkZVAjdal+s7s0MwaRv9igoPqLRdzOLzw/8Xvq8= github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= @@ -84,24 +61,18 @@ github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbi github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= -github.com/GoogleCloudPlatform/cloudsql-proxy v0.0.0-20191009163259-e802c2cb94ae/go.mod h1:mjwGPas4yKduTyubHvD1Atl9r1rUq8DfVy+gkVvZ+oo= github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace v1.13.0 h1:aRQEQ57Mw12h0tG8oo2UGC5d8fpUFCvD1lcS9fdGh6I= github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace v1.13.0/go.mod h1:WzE/bKzbWw91rEv1w53y4taJheFSkUzp2Mu8uItorHg= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.37.0 h1:+3ioRuJPNQk6WkbdClWVo8FyfpXu/ZXePQ3syDwrN4o= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.37.0 h1:k5x4SiDgKS8wVQO/ww1fnoh5gwYEg6Wsi+1z5kB9uDM= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.37.0/go.mod h1:oEccMakRmMNrayCPR+5OmZE/aeXmTPzUtmomEXIPBdI= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= -github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= -github.com/Masterminds/semver/v3 v3.0.3/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= -github.com/Masterminds/semver/v3 v3.1.0/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= -github.com/Masterminds/sprig v2.15.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60= github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= github.com/Masterminds/squirrel v1.5.4 h1:uUcX/aBc8O7Fg9kaISIUsHXdKuqehiXAMQTYX8afzqM= @@ -118,8 +89,6 @@ github.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm github.com/ajstarks/deck/generate v0.0.0-20210309230005-c3f852c02e19/go.mod h1:T13YZdzov6OU0A1+RfKZiZN9ca6VeKdBdyDV+BY97Tk= github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b h1:slYM766cy2nI3BwyRiyQj/Ud48djTMtMebDqepE95rw= github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b/go.mod h1:1KcenG0jGWcpt8ov532z81sp/kMMUG485J2InIOyADM= -github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= -github.com/alecthomas/kingpin v2.2.6+incompatible/go.mod h1:59OFYbFVLKQKq+mqrL6Rw5bR0c3ACQaawgXx0QYndlE= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -131,32 +100,17 @@ github.com/allegro/bigcache v1.2.1/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2uc github.com/amdonov/xmlsig v0.1.0 h1:i0iQ3neKLmUhcfIRgiiR3eRPKgXZj+n5lAfqnfKoeXI= github.com/amdonov/xmlsig v0.1.0/go.mod h1:jTR/jO0E8fSl/cLvMesP+RjxyV4Ux4WL1Ip64ZnQpA0= github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= -github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/aokoli/goutils v1.0.1/go.mod h1:SijmP0QR8LtwsmDs8Yii5Z/S4trXFGFC2oO5g9DP+DQ= -github.com/apache/beam v2.28.0+incompatible/go.mod h1:/8NX3Qi8vGstDLLaeaU7+lzVEu/ACaQhYjeefzQ0y1o= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/apex/log v1.1.4/go.mod h1:AlpoD9aScyQfJDVHmLMEcx4oU6LqzkWp4Mg9GdAcEvQ= -github.com/apex/logs v0.0.4/go.mod h1:XzxuLZ5myVHDy9SAmYpamKKRNApGj54PfYLcFrXqDwo= -github.com/aphistic/golf v0.0.0-20180712155816-02c07f170c5a/go.mod h1:3NqKYiepwy8kCu4PNA+aP7WUV72eXWJeP9/r3/K9aLE= -github.com/aphistic/sweet v0.2.0/go.mod h1:fWDlIh/isSE9n6EPsRmC0det+whmX6dJid3stzu0Xys= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= -github.com/aws/aws-sdk-go v1.15.27/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= -github.com/aws/aws-sdk-go v1.19.18/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.19.45/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.20.6/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.25.11/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= -github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59/go.mod h1:q/89r3U2H7sSsE2t6Kca0lfwTK8JdoNGS/yzM/4iH5I= github.com/beevik/etree v1.1.0 h1:T0xke/WvNtMoCqgzPhkX2r4rjY3GDZFi+FjpRZY2Jbs= github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= @@ -167,24 +121,15 @@ github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+Ce github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= -github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI= github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/boombuler/barcode v1.0.1 h1:NDBbPmhS+EqABEs5Kg3n/5ZNjy73Pz7SIV+KCeqyXcs= github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= -github.com/caarlos0/ctrlc v1.0.0/go.mod h1:CdXpj4rmq0q/1Eb44M9zi2nKB0QraNKuRGYGrrHhcQw= -github.com/campoy/unique v0.0.0-20180121183637-88950e537e7e/go.mod h1:9IOqJGCPMSc6E5ydlp5NIonxObaeu/Iub/X03EKPVYo= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= -github.com/cavaliercoder/go-cpio v0.0.0-20180626203310-925f9528c45e/go.mod h1:oDpT4efm8tSYHXV5tHSdRvBet/b/QzxZ+XyyPehvm3A= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/cenkalti/backoff/v4 v4.2.0 h1:HN5dHm3WBOgndBH6E8V0q2jIYIR3s9yglV8k/+MN3u4= github.com/cenkalti/backoff/v4 v4.2.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= -github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= -github.com/certifi/gocertifi v0.0.0-20210507211836-431795d63e8d/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= @@ -197,14 +142,9 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudflare/backoff v0.0.0-20161212185259-647f3cdfc87a/go.mod h1:rzgs2ZOiguV6/NpiDgADjRLPNyZlApIWxKpkT+X8SdY= -github.com/cloudflare/cfssl v1.6.3 h1:hDhRaGQN55nh0510/7A5QBN3xLoDz/M7nQX80icXvzs= -github.com/cloudflare/cfssl v1.6.3/go.mod h1:Kq0iHKY8sm2klDeQ2Ci/FI+6QdBGuyPWodgTJFLrXIw= -github.com/cloudflare/redoctober v0.0.0-20201013214028-99c99a8e7544/go.mod h1:6Se34jNoqrd8bTxrmJB2Bg2aoZ2CdSXonils9NsiNgo= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20210322005330-6414d713912e/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= @@ -215,21 +155,14 @@ github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMe github.com/cockroachdb/cockroach-go/v2 v2.3.3 h1:fNmtG6XhoA1DhdDCIu66YyGSsNb1szj4CaAsbDxRmy4= github.com/cockroachdb/cockroach-go/v2 v2.3.3/go.mod h1:1wNJ45eSXW9AnOc3skntW9ZUZz6gxrQK3cOj3rK+BC8= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= -github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo= -github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA= -github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= -github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= @@ -238,19 +171,17 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsr github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd h1:83Wprp6ROGeiHFAP8WJdI2RoxALQYgdllERc3N5N2DM= github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= +github.com/descope/virtualwebauthn v1.0.2 h1:cAvfS9wHh6On9HAE4Gjn3fJkf8MPQW2LzN8BPKEPs0M= +github.com/descope/virtualwebauthn v1.0.2/go.mod h1:iJvinjD1iZYqQ09J5lF0+795OdDbzTWcYQjPD/BF54M= github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I= github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE= -github.com/devigned/tab v0.1.1/go.mod h1:XG9mPq0dFghrYvoBF3xdRrJzSTX1b7IQrvaL9mzjeJY= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/dlclark/regexp2 v1.8.1 h1:6Lcdwya6GjPUNsBct8Lg/yRPwMhABj269AAzdGSiR+0= @@ -295,62 +226,44 @@ github.com/dsoprea/go-utility v0.0.0-20200711062821-fab8125e9bdf/go.mod h1:95+K3 github.com/dsoprea/go-utility v0.0.0-20221003172846-a3e1774ef349 h1:/py11NlxDaOxkT9OKN+gXgT+QOH5xj1ZRoyusfRIlo4= github.com/dsoprea/go-utility v0.0.0-20221003172846-a3e1774ef349/go.mod h1:KVK+/Hul09ujXAGq+42UBgCTnXkiJZRnLYdURGjQUwo= github.com/dsoprea/go-utility/v2 v2.0.0-20200717064901-2fccff4aa15e/go.mod h1:uAzdkPTub5Y9yQwXe8W4m2XuP0tK4a9Q/dantD0+uaU= -github.com/duo-labs/webauthn v0.0.0-20221205164246-ebaf9b74c6ec h1:darQ1FPPrwlzwmuN3fRMVCrsaCpuDqkKHADYzcMa73M= -github.com/duo-labs/webauthn v0.0.0-20221205164246-ebaf9b74c6ec/go.mod h1:V3q8IgNpNqFio+56G0vy/QZIi7iho65UFrDwdF5OtZA= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= -github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/envoyproxy/protoc-gen-validate v0.3.0-java/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/envoyproxy/protoc-gen-validate v0.6.1/go.mod h1:txg5va2Qkip90uYoSKH+nkAAmXrb2j3iq4FLwdrCbXQ= github.com/envoyproxy/protoc-gen-validate v0.10.1 h1:c0g45+xCJhdgFGw7a5QAfdS4byAbud7miNWJ1WwEVf8= github.com/envoyproxy/protoc-gen-validate v0.10.1/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss= github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DPaBjB8zlTR87/ElzFsnQfuHnVUVqpZZIcV5Y= github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0= -github.com/etcd-io/gofail v0.0.0-20190801230047-ad7f989257ca/go.mod h1:49H/RkXP8pKaZy4h0d+NW16rSLhyVBt4o6VLJbmOqDE= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= -github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= -github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= -github.com/fortytw2/leaktest v1.2.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= -github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= -github.com/fullstorydev/grpcurl v1.8.0/go.mod h1:Mn2jWbdMrQGJQ8UD62uNyMumT2acsZUCkZIqFxsQf1o= -github.com/fullstorydev/grpcurl v1.8.1/go.mod h1:3BWhvHZwNO7iLXaQlojdg5NA6SxUDePli4ecpK1N7gw= github.com/fxamacker/cbor/v2 v2.4.0 h1:ri0ArlOR+5XunOP8CRUowT0pSJOwhW098ZCUyskZD88= github.com/fxamacker/cbor/v2 v2.4.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo= -github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.7.4 h1:QmUZXrvJ9qZ3GfWvQ+2wnW/1ePrTEJqPKMYEU3lD/DM= github.com/gin-gonic/gin v1.7.4/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY= -github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-asn1-ber/asn1-ber v1.5.4 h1:vXT6d/FNDiELJnLb6hGNa309LMsrCoYFvpwHDF0+Y1A= github.com/go-asn1-ber/asn1-ber v1.5.4/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= @@ -361,7 +274,6 @@ github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3Bop github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= @@ -383,15 +295,17 @@ github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD87 github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE= github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= -github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU= github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-webauthn/revoke v0.1.9 h1:gSJ1ckA9VaKA2GN4Ukp+kiGTk1/EXtaDb1YE8RknbS0= +github.com/go-webauthn/revoke v0.1.9/go.mod h1:j6WKPnv0HovtEs++paan9g3ar46gm1NarktkXBaPR+w= +github.com/go-webauthn/webauthn v0.8.2 h1:8KLIbpldjz9KVGHfqEgJNbkhd7bbRXhNw4QWFJE15oA= +github.com/go-webauthn/webauthn v0.8.2/go.mod h1:d+ezx/jMCNDiqSMzOchuynKb9CVU1NM9BumOnokfcVQ= github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM= github.com/go-xmlfmt/xmlfmt v1.1.2 h1:Nea7b4icn8s57fTx1M5AI4qQT5HEM3rVUO8MuE6g80U= github.com/go-xmlfmt/xmlfmt v1.1.2/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM= @@ -401,8 +315,6 @@ github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= -github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= @@ -412,8 +324,6 @@ github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFG github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= -github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= @@ -425,7 +335,6 @@ github.com/golang/geo v0.0.0-20200319012246-673a6f80352d/go.mod h1:QZ0nwyI2jOfgR github.com/golang/geo v0.0.0-20230404232722-c4acd7a044dc h1:WkAZHSmcnJhZyutVoVXe7lDSQBbISxITcm57tYf22PE= github.com/golang/geo v0.0.0-20230404232722-c4acd7a044dc/go.mod h1:8wI0hitZ3a1IxZfeH3/5I97CI8i5cLGsYe7xNhQGs9U= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v0.0.0-20210429001901-424d2337a529/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= github.com/golang/glog v1.1.1 h1:jxpi2eWoU84wbX9iIEyAeeoac3FLuifZpY9tcNUD9kw= github.com/golang/glog v1.1.1/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= @@ -443,7 +352,6 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -461,7 +369,6 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= @@ -470,12 +377,6 @@ github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= -github.com/google/certificate-transparency-go v1.0.21/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg= -github.com/google/certificate-transparency-go v1.1.2-0.20210422104406-9f33727a7a18/go.mod h1:6CKh9dscIRoqc2kC6YUFICHZMT9NrClyPrRVFrdw1QQ= -github.com/google/certificate-transparency-go v1.1.2-0.20210511102531-373a877eec92/go.mod h1:kXWPsHVPSKVuxPPG69BRtumCbAW537FydV/GH89oBhM= -github.com/google/certificate-transparency-go v1.1.4 h1:hCyXHDbtqlr/lMXU0D4WgbalXL0Zk4dSWWMbPV8VrqY= -github.com/google/certificate-transparency-go v1.1.4/go.mod h1:D6lvbfwckhNrbM9WVl1EVeMOyzC19mpIjMOI4nxBHtQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -490,16 +391,15 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-github/v28 v28.1.1/go.mod h1:bsqJWQX05omyWVmc00nEUql9mhQyv38lDZ8kPZcQVoM= -github.com/google/go-licenses v0.0.0-20210329231322-ce1d9163b77d/go.mod h1:+TYOmkVoJOpwnS0wfdsJCV9CoD5nJYsHoFk/0CrTK4M= -github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= -github.com/google/go-replayers/grpcreplay v0.1.0/go.mod h1:8Ig2Idjpr6gifRd6pNVggX6TC1Zw6Jx74AKp7QNH2QE= -github.com/google/go-replayers/httpreplay v0.1.0/go.mod h1:YKZViNhiGgqdBlUbI2MwGpq4pXxNmhJLPHQ7cv2b5no= +github.com/google/go-tpm v0.1.2-0.20190725015402-ae6dd98980d4/go.mod h1:H9HbmUG2YgV/PHITkO7p6wxEEj/v5nlsVWIwumwH2NI= +github.com/google/go-tpm v0.3.0/go.mod h1:iVLWvrPp/bHeEkxTFi9WG6K9w0iy2yIszHwZGHPbzAw= +github.com/google/go-tpm v0.3.3 h1:P/ZFNBZYXRxc+z7i5uyd8VP7MaDteuLZInzrH2idRGo= +github.com/google/go-tpm v0.3.3/go.mod h1:9Hyn3rgnzWF9XBWVk6ml6A6hNkbWjNFlDQL51BeghL4= +github.com/google/go-tpm-tools v0.0.0-20190906225433-1614c142f845/go.mod h1:AVfHadzbdzHo54inR2x1v640jdi1YSi3NauM2DUsxk0= +github.com/google/go-tpm-tools v0.2.0/go.mod h1:npUd03rQ60lxN7tzeBJreG38RvWwme2N1reF/eeiBk4= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/licenseclassifier v0.0.0-20210325184830-bb04aff29e72/go.mod h1:qsqn2hxC+vURpyBRygGUuinTO42MFRLcsmQ/P8v94+M= +github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+incompatible h1:xmapqc1AyLoB+ddYT6r04bD9lIjlOqGaREovi0SzFaE= -github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw= @@ -513,27 +413,16 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg= github.com/google/pprof v0.0.0-20230323073829-e72429f035bd h1:r8yyd+DJDmsUhGrRBxH5Pj7KeFK5l+Y3FsgT8keqKtk= github.com/google/pprof v0.0.0-20230323073829-e72429f035bd/go.mod h1:79YE0hCXdHag9sBkw2o+N/YnZtTkXi0UT9Nnixa5eYk= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/rpmpack v0.0.0-20191226140753-aa36bfddb3a0/go.mod h1:RaTPr0KUf2K7fnZYLNDrr8rxAamWs3iNywJLtQ2AzBg= -github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= -github.com/google/trillian v1.3.14-0.20210409160123-c5ea3abd4a41/go.mod h1:1dPv0CUjNQVFEDuAUFhZql16pw/VlPgaX8qj+g5pVzQ= -github.com/google/trillian v1.3.14-0.20210428093031-b4ddea2e86b1/go.mod h1:FdIJX+NoDk/dIN2ZxTyz5nAJWgf+NSSSriPAMThChTY= -github.com/google/uuid v0.0.0-20161128191214-064e2069ce9c/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/wire v0.3.0/go.mod h1:i1DMg/Lu8Sz5yYl25iOdmc5CT5qusaa+zmRWs16741s= github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k= github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= -github.com/googleapis/gax-go v2.0.2+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.8.0 h1:UBtEZqx1bjXtOQ5BVTkuYghXrr3N4V123VKJK67vJZc= @@ -541,9 +430,6 @@ github.com/googleapis/gax-go/v2 v2.8.0/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38 github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU= -github.com/goreleaser/goreleaser v0.134.0/go.mod h1:ZT6Y2rSYa6NxQzIsdfWWNWAlYGXGbreo66NmE+3X3WQ= -github.com/goreleaser/nfpm v1.2.1/go.mod h1:TtWrABZozuLOttX2uDlYyECfQX7x5XYkVxhjYcR6G9w= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/csrf v1.7.1 h1:Ir3o2c1/Uzj6FBxMlAUB6SivgVMy1ONXwYgXn+/aHPE= github.com/gorilla/csrf v1.7.1/go.mod h1:+a/4tCmqhG6/w4oafeAZ9pEa3/NZOWYVbD9fV0FwIQA= @@ -565,15 +451,11 @@ github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/ad github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= -github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI= github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.9.2/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.14.6/go.mod h1:zdiPV4Yse/1gnckTHtghG4GkDEdKCRJduHpTxT3/jcw= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= @@ -586,17 +468,13 @@ github.com/h2non/gock v1.2.0 h1:K6ol8rfrRkUOefooBC8elXoaNGYkpp7y2qcxGG6BzUE= github.com/h2non/gock v1.2.0/go.mod h1:tNhoxHYW2W42cYkYb1WqzdbYIieALC99kpYr7rH/BQk= github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw= github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI= -github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= -github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-retryablehttp v0.6.4/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= @@ -613,18 +491,12 @@ github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0m github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/huandu/xstrings v1.0.0/go.mod h1:4qWG/gcEcfX4z/mBDHJ++3ReCw9ibxbsNJbcucJdbSo= -github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4= github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU= github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= -github.com/iancoleman/strcase v0.0.0-20180726023541-3605ed457bf7/go.mod h1:SK73tn/9oHe+/Y0h39VT4UCxmurVJkR5NA7kMEAOgSE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= -github.com/imdario/mergo v0.3.4/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM= github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/improbable-eng/grpc-web v0.15.0 h1:BN+7z6uNXZ1tQGcNAuaU1YjsLTApzkjt2tzCixLaUPQ= @@ -681,44 +553,33 @@ github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0f github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= -github.com/jarcoal/httpmock v1.0.5/go.mod h1:ATjnClrvW/3tijVmpL/va5Z3aAyGvqU3gCT8nX0Txik= github.com/jarcoal/jpath v0.0.0-20140328210829-f76b8b2dbf52 h1:jny9eqYPwkG8IVy7foUoRjQmFLcArCSz+uPsL6KS0HQ= github.com/jarcoal/jpath v0.0.0-20140328210829-f76b8b2dbf52/go.mod h1:RDZ+4PR3mDOtTpVbI0qBE+rdhmtIrtbssiNn38/1OWA= -github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jeremija/gosubmit v0.2.7 h1:At0OhGCFGPXyjPYAsCchoBUhE099pcBXmsb4iZqROIc= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jhump/protoreflect v1.6.1/go.mod h1:RZQ/lnuN+zqeRVpQigTwO6o0AJUkxbnSnpuG7toUTG4= -github.com/jhump/protoreflect v1.8.2/go.mod h1:7GcYQDdMU/O/BBrl/cX6PNHpXh6cenjd8pneu5yW7Tg= github.com/jinzhu/gorm v1.9.16 h1:+IyIjPEABKRpsu/F8OvDPy9fyQlgsg2luMV2ZIH5i5o= github.com/jinzhu/gorm v1.9.16/go.mod h1:G3LB3wezTOWM2ITLzPxEXgSkOXAntiLHS7UdBefADcs= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jinzhu/now v1.1.4 h1:tHnRBy1i5F2Dh8BAFxqFzxKqqvezXrL2OW1TnX+Mlas= -github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmhodges/clock v0.0.0-20160418191101-880ee4c33548/go.mod h1:hGT6jSUVzF6no3QaDSMLGLEHtHSBSefs+MgcDWnmhmo= -github.com/jmoiron/sqlx v1.3.3/go.mod h1:2BljVx/86SuTyjE+aPYlHCTNvZrnJXghYGpNiXLBMCQ= -github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4= github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc= -github.com/jpillora/backoff v0.0.0-20180909062703-3050d21c67d7/go.mod h1:2iMrUgbbvHEiQClaW2NsSzMyGHqN+rDFqY705q49KG0= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/juju/ratelimit v1.0.1/go.mod h1:qapgC/Gy+xNh9UxzV13HGGl/6UXNN+ct+vwSgWNm/qk= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/k3a/html2text v1.1.0 h1:ks4hKSTdiTRsLr0DM771mI5TvsoG6zH7m1Ulv7eJRHw= @@ -727,15 +588,11 @@ github.com/kevinburke/go-types v0.0.0-20210723172823-2deba1f80ba7 h1:K8qael4Lems github.com/kevinburke/go-types v0.0.0-20210723172823-2deba1f80ba7/go.mod h1:/Pk5i/SqYdYv1cie5wGwoZ4P6TpgMi+Yf58mtJSHdOw= github.com/kevinburke/rest v0.0.0-20230306061549-8f487d822ad0 h1:2b9anKtyO/UTUQb+TAdPAW+w0p9xCIvng4fdZJ2xsYk= github.com/kevinburke/rest v0.0.0-20230306061549-8f487d822ad0/go.mod h1:pD+iEcdAGVXld5foVN4e24zb/6fnb60tgZPZ3P/3T/I= -github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kevinburke/twilio-go v0.0.0-20221122012537-65f3dd7539e2 h1:k+lYMvS9cAl7e4Ea78qodfa6QZfXNa4QlFS/0GYpanI= github.com/kevinburke/twilio-go v0.0.0-20221122012537-65f3dd7539e2/go.mod h1:PDdDH7RSKjjy9iFyoMzfeChOSmXpXuMEUqmAJSihxx4= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= -github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/kisielk/sqlstruct v0.0.0-20201105191214-5f3e10d3ab46/go.mod h1:yyMNCyc/Ib3bDTKd379tNMpB/7/H5TjM2Y9QJ5THLbE= -github.com/kisom/goutils v1.4.3/go.mod h1:Lp5qrquG7yhYnWzZCI/68Pa/GpFynw//od6EkGnWpac= github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.16.4 h1:91KN02FnsOYhuunwU4ssRe8lc2JosWmizWa91B5v1PU= @@ -758,20 +615,16 @@ github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/kylelemons/go-gypsy v1.0.0/go.mod h1:chkXM0zjdpXOiqkCW1XcCHDfjfk14PH2KKkQWxfJUcU= -github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 h1:SOEGU9fKiNWd/HOJuq6+3iTQz8KNCLtVX6idSoTLdUw= github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o= github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 h1:P6pPBnrTSX3DEVR4fDembhRWSsG5rVo6hYhAB/ADZrk= github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6FmdpVm2joNMFikkuWg0EoCKLGUMNw= github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= -github.com/letsencrypt/pkcs11key/v4 v4.0.0/go.mod h1:EFUvBDay26dErnNb70Nd0/VW3tJiIbETBPTl9ATXQag= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.10.1/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= @@ -779,44 +632,27 @@ github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-b github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= -github.com/lyft/protoc-gen-star v0.5.1/go.mod h1:9toiA3cC7z5uVbODF7kEQ91Xn7XNFkVUl+SrEe+ZORU= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= -github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= -github.com/mattn/go-shellwords v1.0.10/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus= -github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= -github.com/mattn/go-sqlite3 v1.14.7/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U= github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -github.com/mattn/go-zglob v0.0.1/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/miekg/pkcs11 v1.0.2/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= -github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34= github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM= github.com/minio/minio-go/v7 v7.0.50 h1:4IL4V8m/kI90ZL6GupCARZVrBv8/XrcKcJhaJ3iz68k= @@ -824,7 +660,6 @@ github.com/minio/minio-go/v7 v7.0.50/go.mod h1:IbbodHyjUAguneyucUaahv+VMNs/EOTV9 github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= -github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= @@ -836,8 +671,6 @@ github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:F github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -847,8 +680,6 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= -github.com/mreiferson/go-httpclient v0.0.0-20160630210159-31f0106b4474/go.mod h1:OQA4XLvDbMgS8P0CevmM4m9Q3Jq4phKUzcocxuGJ5m8= github.com/muesli/clusters v0.0.0-20180605185049-a07a36e67d36/go.mod h1:mw5KDqUj0eLj/6DUNINLVJNoPTFkEuGMHtJsXLviLkY= github.com/muesli/clusters v0.0.0-20200529215643-2700303c1762 h1:p4A2Jx7Lm3NV98VRMKlyWd3nqf8obft8NfXlAUmqd3I= github.com/muesli/clusters v0.0.0-20200529215643-2700303c1762/go.mod h1:mw5KDqUj0eLj/6DUNINLVJNoPTFkEuGMHtJsXLviLkY= @@ -861,8 +692,6 @@ github.com/muhlemmer/gu v0.3.1/go.mod h1:YHtHR+gxM+bKEIIs7Hmi9sPT3ZDUvTN/i88wQpZ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mwitkow/go-proto-validators v0.0.0-20180403085117-0950a7990007/go.mod h1:m2XC9Qq0AlmmVksL6FktJCdTYyLk7V3fKyp0sl1yWQo= -github.com/mwitkow/go-proto-validators v0.2.0/go.mod h1:ZfA1hW+UH/2ZHOWvQ3HnQaU0DtnpXu850MZiy+YUgcc= github.com/mwitkow/grpc-proxy v0.0.0-20181017164139-0f1106ef9c76/go.mod h1:x5OoJHDHqxHS801UIuhqGl6QdSAEJvtausosHSdazIo= github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= @@ -875,19 +704,13 @@ github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32 h1:W6apQkHrMkS0Muv8G/TipAy github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms= github.com/nicksnyder/go-i18n/v2 v2.2.1 h1:aOzRCdwsJuoExfZhoiXHy4bjruwCMdt5otbYojM/PaA= github.com/nicksnyder/go-i18n/v2 v2.2.1/go.mod h1:fF2++lPHlo+/kPaj3nB0uxtPwzlPm+BlgwGX7MkeGj0= -github.com/nishanths/predeclared v0.0.0-20200524104333-86fad755b4d3/go.mod h1:nt3d53pc1VYcphSCIaYAJtnPYnr3Zyn8fMq2wvPGPso= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA= -github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= @@ -897,15 +720,9 @@ github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxS github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw= -github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= -github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= -github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= -github.com/otiai10/mint v1.3.1/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= -github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml/v2 v2.0.7 h1:muncTPStnKRos5dpVKULv2FVd4bMOhNePj9CjgDb8Us= github.com/pelletier/go-toml/v2 v2.0.7/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= @@ -918,9 +735,7 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= -github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= -github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= @@ -931,9 +746,7 @@ github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= -github.com/prometheus/client_golang v1.5.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.10.0/go.mod h1:WJM3cc3yu7XKBKa/I8WeZm+V3eltZnBwfENSU7mdogU= github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= @@ -949,11 +762,8 @@ github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= -github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= -github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= -github.com/prometheus/common v0.24.0/go.mod h1:H6QK/N6XVT42whUeIdI3dp36w49c+/iMDk7UAI2qm7Q= github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= @@ -962,29 +772,22 @@ github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7z github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.3.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/pseudomuto/protoc-gen-doc v1.4.1/go.mod h1:exDTOVwqpp30eV/EDPFLZy3Pwr2sn6hBC1WIYH/UbIg= -github.com/pseudomuto/protokit v0.2.0/go.mod h1:2PdH30hxVHsup8KpBTOXTBeMVhJZVio3Q8ViKSAXT0Q= github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= -github.com/rogpeppe/fastuuid v1.1.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= -github.com/rs/cors v1.8.3 h1:O+qNyWn7Z+F9M0ILBHgMVPuB1xTOucVd5gtaYyXBpRo= -github.com/rs/cors v1.8.3/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/rs/cors v1.9.0 h1:l9HGsTsHJcvW14Nk7J9KFz8bzeAWXn3CG6bgt7LsrAE= +github.com/rs/cors v1.9.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/xid v1.4.0 h1:qd7wPTDkN6KQx2VmMBLrpHkiyQwgFXRnkOLacUiaSNY= github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= @@ -997,42 +800,31 @@ github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= -github.com/sassoftware/go-rpmutils v0.0.0-20190420191620-a8f1baeba37b/go.mod h1:am+Fp8Bt506lA3Rk3QCmSqmYmLMnPDhdDUcosQCAx+I= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= -github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sirupsen/logrus v1.9.2 h1:oxx1eChJGI6Uks2ZC4W1zpLlVgqB8ner4EuQwV4Ik1Y= +github.com/sirupsen/logrus v1.9.2/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v1.0.0 h1:UVQPSSmc3qtTi+zPPkCXvZX9VvW/xT/NsRvKfwY81a8= github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= -github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9/go.mod h1:SnhjPscd9TpLiy1LpzGSKh3bXCfxxXuqd9xmQJy3slM= github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/smartystreets/gunit v1.0.0/go.mod h1:qwPWnhz6pn0NnRBP++URONOVyNkPyr4SauJk4cUOwJs= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/soheilhy/cmux v0.1.5-0.20210205191134-5ec6847320e5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= -github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/sony/sonyflake v1.1.0 h1:wnrEcL3aOkWmPlhScLEGAXKkLAIslnBteNUq4Bw6MM4= github.com/sony/sonyflake v1.1.0/go.mod h1:LORtCywH/cq10ZbyfhKrHYgAUGH7mOBa76enV9txy/Y= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= -github.com/spf13/afero v1.3.4/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM= github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= @@ -1041,8 +833,6 @@ github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155 github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= -github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= -github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= @@ -1054,10 +844,8 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= -github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/spf13/viper v1.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU= github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA= -github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= @@ -1066,7 +854,6 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v0.0.0-20170130113145-4d4bfba8f1d1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -1077,22 +864,14 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= +github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/superseriousbusiness/exifremove v0.0.0-20210330092427-6acd27eac203 h1:1SWXcTphBQjYGWRRxLFIAR1LVtQEj4eR7xPtyeOVM/c= github.com/superseriousbusiness/exifremove v0.0.0-20210330092427-6acd27eac203/go.mod h1:0Xw5cYMOYpgaWs+OOSx41ugycl2qvKTi9tlMMcZhFyY= -github.com/tj/assert v0.0.0-20171129193455-018094318fb0/go.mod h1:mZ9/Rh9oLWpLLDRpvE+3b7gP/C2YyLFYxNmcLnPTMe0= -github.com/tj/go-elastic v0.0.0-20171221160941-36157cbbebc2/go.mod h1:WjeM0Oo1eNAjXGDx2yma7uG2XoyRZTq1uv3M/o7imD0= -github.com/tj/go-kinesis v0.0.0-20171128231115-08b17f58cb1b/go.mod h1:/yhzCV0xPfx6jb1bBgRFjl5lytqVqZXEaeqWP8lTEao= -github.com/tj/go-spin v1.1.0/go.mod h1:Mg1mzmePZm4dva8Qz60H2lHwmJ2loum4VIrLgVnKwh4= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tmc/grpc-websocket-proxy v0.0.0-20200427203606-3cfed13b9966/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce/go.mod h1:o8v6yHRoik09Xen7gje4m9ERNah1d1PPsVq1VEx9vE4= github.com/ttacon/builder v0.0.0-20170518171403-c099f663e1c2 h1:5u+EJUQiosu3JFX0XS0qTf5FznsMOzTjGqavBGuCbo0= github.com/ttacon/builder v0.0.0-20170518171403-c099f663e1c2/go.mod h1:4kyMkleCiLkgY6z8gK5BkI01ChBtxR0ro3I1ZDcGM3w= github.com/ttacon/libphonenumber v1.2.1 h1:fzOfY5zUADkCkbIafAed11gL1sW+bJ26p6zWLBMElR4= @@ -1103,20 +882,11 @@ github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVM github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= -github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= -github.com/ulikunitz/xz v0.5.7/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/wcharczuk/go-chart/v2 v2.1.0/go.mod h1:yx7MvAVNcP/kN9lKXM/NTce4au4DFN99j6i1OwDclNA= -github.com/weppos/publicsuffix-go v0.13.1-0.20210123135404-5fd73613514e/go.mod h1:HYux0V0Zi04bHNwOHy4cXJVz/TQjYonnF6aoYhj+3QE= -github.com/weppos/publicsuffix-go v0.15.1-0.20210511084619-b1f36a2d6c0b/go.mod h1:HYux0V0Zi04bHNwOHy4cXJVz/TQjYonnF6aoYhj+3QE= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= -github.com/xanzy/go-gitlab v0.31.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug= -github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= -github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= @@ -1130,30 +900,13 @@ github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5t github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= github.com/zitadel/logging v0.3.4 h1:9hZsTjMMTE3X2LUi0xcF9Q9EdLo+FAezeu52ireBbHM= github.com/zitadel/logging v0.3.4/go.mod h1:aPpLQhE+v6ocNK0TWrBrd363hZ95KcI17Q1ixAQwZF0= -github.com/zitadel/oidc/v2 v2.4.0 h1:BKx61qOxDf+GjrY8T6lFxPjea0aMfkFvHD9pqyJGpFk= -github.com/zitadel/oidc/v2 v2.4.0/go.mod h1:wBOrfB0m/tGXo6isym1F5k3VeXSUinGsAt2H8V/+Uks= +github.com/zitadel/oidc/v2 v2.6.1 h1:NIW4/KPi9Q2Pae6MKEhrSl+DSC5W4574GlboHildroc= +github.com/zitadel/oidc/v2 v2.6.1/go.mod h1:vsFNrYCj2x0it0pYmIRVZ12HJ1VGaMVyGl7HLqw5p+Y= github.com/zitadel/saml v0.0.11 h1:kObucnBrcu1PHCO7RGT0iVeuJL/5I50gUgr40S41nMs= github.com/zitadel/saml v0.0.11/go.mod h1:YGWAvPZRv4DbEZ78Ht/2P0AWzGn+6WGhFf90PMXl0Po= -github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= -github.com/zmap/rc2 v0.0.0-20131011165748-24b9757f5521/go.mod h1:3YZ9o3WnatTIZhuOtot4IcUfzoKVjUHqu6WALIyI0nE= -github.com/zmap/zcertificate v0.0.0-20180516150559-0e3d58b1bac4/go.mod h1:5iU54tB79AMBcySS0R2XIyZBAVmeHranShAFELYx7is= -github.com/zmap/zcrypto v0.0.0-20210123152837-9cf5beac6d91/go.mod h1:R/deQh6+tSWlgI9tb4jNmXxn8nSCabl5ZQsBX9//I/E= -github.com/zmap/zcrypto v0.0.0-20210511125630-18f1e0152cfc/go.mod h1:FM4U1E3NzlNMRnSUTU3P1UdukWhYGifqEsjk9fn7BCk= -github.com/zmap/zlint/v3 v3.1.0/go.mod h1:L7t8s3sEKkb0A2BxGy1IWrxt1ZATa1R4QfJZaQOD3zU= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= -go.etcd.io/etcd/api/v3 v3.5.0-alpha.0/go.mod h1:mPcW6aZJukV6Aa81LSKpBjQXTWlXB5r74ymPoSWa3Sw= -go.etcd.io/etcd/client/v2 v2.305.0-alpha.0/go.mod h1:kdV+xzCJ3luEBSIeQyB/OEKkWKd8Zkux4sbDeANrosU= -go.etcd.io/etcd/client/v3 v3.5.0-alpha.0/go.mod h1:wKt7jgDgf/OfKiYmCq5WFGxOFAkVMLxiiXgLDFhECr8= -go.etcd.io/etcd/etcdctl/v3 v3.5.0-alpha.0/go.mod h1:YPwSaBciV5G6Gpt435AasAG3ROetZsKNUzibRa/++oo= -go.etcd.io/etcd/pkg/v3 v3.5.0-alpha.0/go.mod h1:tV31atvwzcybuqejDoY3oaNRTtlD2l/Ot78Pc9w7DMY= -go.etcd.io/etcd/raft/v3 v3.5.0-alpha.0/go.mod h1:FAwse6Zlm5v4tEWZaTjmNhe17Int4Oxbu7+2r0DiD3w= -go.etcd.io/etcd/server/v3 v3.5.0-alpha.0/go.mod h1:tsKetYpt980ZTpzl/gb+UOJj9RkIyCb1u4wjzMg90BQ= -go.etcd.io/etcd/tests/v3 v3.5.0-alpha.0/go.mod h1:HnrHxjyCuZ8YDt8PYVyQQ5d1ZQfzJVEtQWllr5Vp/30= -go.etcd.io/etcd/v3 v3.5.0-alpha.0/go.mod h1:JZ79d3LV6NUfPjUxXrpiFAYcjhT+06qqw+i28snx8To= -go.opencensus.io v0.15.0/go.mod h1:UffZAU+4sDEINUGP/B7UfBBkq4fqLu9zXAX7ke6CHW0= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= @@ -1162,7 +915,6 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= -go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.40.0 h1:5jD3teb4Qh7mx/nfzq4jO2WFFpvXD0vYWFDrdvNWmXk= @@ -1203,36 +955,26 @@ go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/ go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= -gocloud.dev v0.19.0/go.mod h1:SmKwiR8YwIMMJvQBKLsC3fHNyMwXLw3PMDO+VVteJMI= -golang.org/x/crypto v0.0.0-20180501155221-613d6eafa307/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= -golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191117063200-497ca9f6d64f/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201124201722-c8d3bf9c5392/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= @@ -1240,10 +982,9 @@ golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220824171710-5757bc0c5503/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= -golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= -golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= +golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= +golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1269,7 +1010,6 @@ golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRu golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -1289,7 +1029,6 @@ golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181108082009-03003ca0c849/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1303,14 +1042,10 @@ golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190619014844-b5b0513f8c1b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191119073136-fc4aabc6c914/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -1330,24 +1065,19 @@ golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= -golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1355,18 +1085,13 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210413134643-5e61552d6c78/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210427180440-81ed05c6b58c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.7.0 h1:qe6s0zUXlPX80/dITx3440hWZ7GwMwgDDyrSGTPJG/g= -golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4= +golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8= +golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1387,7 +1112,6 @@ golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1396,14 +1120,12 @@ golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190620070143-6f217b454f45/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191119060738-e882bf8e40c2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1427,25 +1149,17 @@ golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201126233918-771906719818/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210412220455-f1c623a9e750/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210629170331-7dc0b73dc9fb/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220207234003-57398862261d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1457,8 +1171,8 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= -golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1483,19 +1197,15 @@ golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190422233926-fe54fb35175b/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= @@ -1503,19 +1213,15 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190729092621-ff9f1409240a/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191010075000-0337d82405ff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191118222007-07fc4c7f2b98/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -1533,19 +1239,15 @@ golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200426102838-f3a5411a4c3b/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200522201501-cb1345f3a375/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200717024301-6ddee64345a6/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20201014170642-d1624618ad65/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= @@ -1567,12 +1269,9 @@ golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3j golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.5.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.6.0/go.mod h1:btoxGiFvQNVUZQ8W08zLtrVS08CNpINPEfxXxgJL1Q4= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.10.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= @@ -1588,32 +1287,23 @@ google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz513 google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= -google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= -google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= -google.golang.org/api v0.45.0/go.mod h1:ISLIJCedJolbZvDfAk+Ctuq5hf+aJ33WgtUsfyFoLXA= google.golang.org/api v0.115.0 h1:6FFkVvStt4YqXSx3azKyzj7fXerGnVlLJ/eud01nBDE= google.golang.org/api v0.115.0/go.mod h1:9cD4/t6uvd9naoEJFA+M96d0IuB6BqFuyhpw68+mRGg= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.2/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20181107211654-5fc9ac540362/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190508193815-b515fa19cec8/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= -google.golang.org/genproto v0.0.0-20190620144150-6af8c5fc6601/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= @@ -1647,19 +1337,10 @@ google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210126160654-44e461bb6506/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210331142528-b7513248f0ba/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210413151531-c14fb6ef47c3/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= -google.golang.org/genproto v0.0.0-20210510173355-fb37daa5cd7a/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20230403163135-c38d8f061ccd h1:sLpv7bNL1AsX3fdnWh9WVh7ejIzXdOc1RRHGeAmeStU= google.golang.org/genproto v0.0.0-20230403163135-c38d8f061ccd/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= -google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= @@ -1684,13 +1365,10 @@ google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.54.0 h1:EhTqbhiYeixwWQtAEZAxmV9MGqcjEU2mFx52xCzNyag= google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1701,7 +1379,6 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.25.1-0.20200805231151-a709e31e5d12/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= @@ -1714,20 +1391,15 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= -gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= -gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI= gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= -gopkg.in/src-d/go-billy.v4 v4.3.2/go.mod h1:nDjArDMp+XMs1aFAESLRjfGSgfvoYN0hDfzEk0GjC98= -gopkg.in/src-d/go-git-fixtures.v3 v3.5.0/go.mod h1:dLBcvytrw/TYZsNTWCnkNF2DSIlzWYqTe3rJR56Ac7g= -gopkg.in/src-d/go-git.v4 v4.13.1/go.mod h1:nx5NYcxdKxq5fpltdHnPa2Exj4Sx0EclMWZQbYDu2z8= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= @@ -1754,16 +1426,13 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= -honnef.co/go/tools v0.1.4/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= -pack.ag/amqp v0.11.2/go.mod h1:4/cbmt4EJXSKlG6LCfWHoqmN0uFdy5i/+YFz+fTfhV4= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= -sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= diff --git a/internal/api/api.go b/internal/api/api.go index 768f0f1a2e..9952863eb7 100644 --- a/internal/api/api.go +++ b/internal/api/api.go @@ -12,6 +12,7 @@ import ( "google.golang.org/grpc" "google.golang.org/grpc/health" healthpb "google.golang.org/grpc/health/grpc_health_v1" + "google.golang.org/grpc/reflection" internal_authz "github.com/zitadel/zitadel/internal/api/authz" "github.com/zitadel/zitadel/internal/api/grpc/server" @@ -19,24 +20,22 @@ import ( http_mw "github.com/zitadel/zitadel/internal/api/http/middleware" "github.com/zitadel/zitadel/internal/api/ui/login" "github.com/zitadel/zitadel/internal/errors" - "github.com/zitadel/zitadel/internal/logstore" "github.com/zitadel/zitadel/internal/query" "github.com/zitadel/zitadel/internal/telemetry/metrics" "github.com/zitadel/zitadel/internal/telemetry/tracing" ) type API struct { - port uint16 - grpcServer *grpc.Server - verifier *internal_authz.TokenVerifier - health healthCheck - router *mux.Router - http1HostName string - grpcGateway *server.Gateway - healthServer *health.Server - cookieHandler *http_util.CookieHandler - cookieConfig *http_mw.AccessConfig - queries *query.Queries + port uint16 + grpcServer *grpc.Server + verifier *internal_authz.TokenVerifier + health healthCheck + router *mux.Router + http1HostName string + grpcGateway *server.Gateway + healthServer *health.Server + accessInterceptor *http_mw.AccessInterceptor + queries *query.Queries } type healthCheck interface { @@ -51,23 +50,20 @@ func New( verifier *internal_authz.TokenVerifier, authZ internal_authz.Config, tlsConfig *tls.Config, http2HostName, http1HostName string, - accessSvc *logstore.Service, - cookieHandler *http_util.CookieHandler, - cookieConfig *http_mw.AccessConfig, + accessInterceptor *http_mw.AccessInterceptor, ) (_ *API, err error) { api := &API{ - port: port, - verifier: verifier, - health: queries, - router: router, - http1HostName: http1HostName, - cookieConfig: cookieConfig, - cookieHandler: cookieHandler, - queries: queries, + port: port, + verifier: verifier, + health: queries, + router: router, + http1HostName: http1HostName, + queries: queries, + accessInterceptor: accessInterceptor, } - api.grpcServer = server.CreateServer(api.verifier, authZ, queries, http2HostName, tlsConfig, accessSvc) - api.grpcGateway, err = server.CreateGateway(ctx, port, http1HostName, cookieHandler, cookieConfig) + api.grpcServer = server.CreateServer(api.verifier, authZ, queries, http2HostName, tlsConfig, accessInterceptor.AccessService()) + api.grpcGateway, err = server.CreateGateway(ctx, port, http1HostName, accessInterceptor) if err != nil { return nil, err } @@ -76,6 +72,7 @@ func New( api.RegisterHandlerOnPrefix("/debug", api.healthHandler()) api.router.Handle("/", http.RedirectHandler(login.HandlerPrefix, http.StatusFound)) + reflection.Register(api.grpcServer) return api, nil } @@ -90,8 +87,7 @@ func (a *API) RegisterServer(ctx context.Context, grpcServer server.WithGatewayP grpcServer, a.port, a.http1HostName, - a.cookieHandler, - a.cookieConfig, + a.accessInterceptor, a.queries, ) if err != nil { diff --git a/internal/api/authz/user.go b/internal/api/authz/user.go new file mode 100644 index 0000000000..13dc4076fc --- /dev/null +++ b/internal/api/authz/user.go @@ -0,0 +1,16 @@ +package authz + +import ( + "context" + + "github.com/zitadel/zitadel/internal/errors" +) + +// UserIDInCTX checks if the userID +// equals the authenticated user in the context. +func UserIDInCTX(ctx context.Context, userID string) error { + if GetCtxData(ctx).UserID != userID { + return errors.ThrowUnauthenticated(nil, "AUTH-Bohd2", "Errors.User.UserIDWrong") + } + return nil +} diff --git a/internal/api/grpc/admin/import.go b/internal/api/grpc/admin/import.go index 4380393377..f905af1591 100644 --- a/internal/api/grpc/admin/import.go +++ b/internal/api/grpc/admin/import.go @@ -629,7 +629,7 @@ func (s *Server) importData(ctx context.Context, orgs []*admin_pb.DataOrg) (*adm ExternalUserID: userLinks.ProvidedUserId, DisplayName: userLinks.ProvidedUserName, } - if err := s.command.AddUserIDPLink(ctx, userLinks.UserId, org.GetOrgId(), externalIDP); err != nil { + if _, err := s.command.AddUserIDPLink(ctx, userLinks.UserId, org.GetOrgId(), externalIDP); err != nil { errors = append(errors, &admin_pb.ImportDataError{Type: "user_link", Id: userLinks.UserId + "_" + userLinks.IdpId, Message: err.Error()}) if isCtxTimeout(ctx) { return &admin_pb.ImportDataResponse{Errors: errors, Success: success}, count, err diff --git a/internal/api/grpc/fields.go b/internal/api/grpc/fields.go new file mode 100644 index 0000000000..f0c9d30a66 --- /dev/null +++ b/internal/api/grpc/fields.go @@ -0,0 +1,36 @@ +package grpc + +import ( + "testing" + + "google.golang.org/protobuf/reflect/protoreflect" +) + +// AllFieldsSet recusively checks if all values in a message +// have a non-zero value. +func AllFieldsSet(t testing.TB, msg protoreflect.Message, ignoreTypes ...protoreflect.FullName) { + ignore := make(map[protoreflect.FullName]bool, len(ignoreTypes)) + for _, name := range ignoreTypes { + ignore[name] = true + } + + md := msg.Descriptor() + name := md.FullName() + if ignore[name] { + return + } + + fields := md.Fields() + + for i := 0; i < fields.Len(); i++ { + fd := fields.Get(i) + if !msg.Has(fd) { + t.Errorf("not all fields set in %q, missing %q", name, fd.Name()) + continue + } + + if fd.Kind() == protoreflect.MessageKind { + AllFieldsSet(t, msg.Get(fd).Message(), ignoreTypes...) + } + } +} diff --git a/internal/api/grpc/management/user.go b/internal/api/grpc/management/user.go index 4c81243fb6..c9f9cc2e97 100644 --- a/internal/api/grpc/management/user.go +++ b/internal/api/grpc/management/user.go @@ -241,7 +241,6 @@ func AddHumanUserRequestToAddHuman(req *mgmt_pb.AddHumanUserRequest) *command.Ad PasswordChangeRequired: true, Passwordless: false, Register: false, - ExternalIDP: false, } if req.Phone != nil { human.Phone = command.Phone{ diff --git a/internal/api/grpc/probes.go b/internal/api/grpc/probes.go index 21106cf885..8c1c57608f 100644 --- a/internal/api/grpc/probes.go +++ b/internal/api/grpc/probes.go @@ -1,5 +1,12 @@ package grpc +import ( + "path" + + "google.golang.org/grpc" + "google.golang.org/grpc/reflection/grpc_reflection_v1alpha" +) + const ( Healthz = "/Healthz" Readiness = "/Ready" @@ -9,3 +16,18 @@ const ( var ( Probes = []string{Healthz, Readiness, Validation} ) + +func init() { + Probes = append(Probes, AllPaths(grpc_reflection_v1alpha.ServerReflection_ServiceDesc)...) +} + +func AllPaths(sd grpc.ServiceDesc) []string { + paths := make([]string, 0, len(sd.Methods)+len(sd.Streams)) + for _, method := range sd.Methods { + paths = append(paths, path.Join("/", sd.ServiceName, method.MethodName)) + } + for _, stream := range sd.Streams { + paths = append(paths, path.Join("/", sd.ServiceName, stream.StreamName)) + } + return paths +} diff --git a/internal/api/grpc/probes_test.go b/internal/api/grpc/probes_test.go new file mode 100644 index 0000000000..96ff0e57e3 --- /dev/null +++ b/internal/api/grpc/probes_test.go @@ -0,0 +1,32 @@ +package grpc + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "google.golang.org/grpc" + "google.golang.org/grpc/reflection/grpc_reflection_v1alpha" +) + +func TestAllPaths(t *testing.T) { + type args struct { + sd grpc.ServiceDesc + } + tests := []struct { + name string + args args + want []string + }{ + { + name: "server reflection", + args: args{grpc_reflection_v1alpha.ServerReflection_ServiceDesc}, + want: []string{"/grpc.reflection.v1alpha.ServerReflection/ServerReflectionInfo"}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := AllPaths(tt.args.sd) + assert.Equal(t, tt.want, got) + }) + } +} diff --git a/internal/api/grpc/server/gateway.go b/internal/api/grpc/server/gateway.go index 9798e5dbd0..dc69ec75e5 100644 --- a/internal/api/grpc/server/gateway.go +++ b/internal/api/grpc/server/gateway.go @@ -16,7 +16,6 @@ import ( client_middleware "github.com/zitadel/zitadel/internal/api/grpc/client/middleware" "github.com/zitadel/zitadel/internal/api/grpc/server/middleware" - http_utils "github.com/zitadel/zitadel/internal/api/http" http_mw "github.com/zitadel/zitadel/internal/api/http/middleware" "github.com/zitadel/zitadel/internal/query" ) @@ -66,16 +65,15 @@ var ( ) type Gateway struct { - mux *runtime.ServeMux - http1HostName string - connection *grpc.ClientConn - cookieHandler *http_utils.CookieHandler - cookieConfig *http_mw.AccessConfig - queries *query.Queries + mux *runtime.ServeMux + http1HostName string + connection *grpc.ClientConn + accessInterceptor *http_mw.AccessInterceptor + queries *query.Queries } func (g *Gateway) Handler() http.Handler { - return addInterceptors(g.mux, g.http1HostName, g.cookieHandler, g.cookieConfig, g.queries) + return addInterceptors(g.mux, g.http1HostName, g.accessInterceptor, g.queries) } type CustomHTTPResponse interface { @@ -89,8 +87,7 @@ func CreateGatewayWithPrefix( g WithGatewayPrefix, port uint16, http1HostName string, - cookieHandler *http_utils.CookieHandler, - cookieConfig *http_mw.AccessConfig, + accessInterceptor *http_mw.AccessInterceptor, queries *query.Queries, ) (http.Handler, string, error) { runtimeMux := runtime.NewServeMux(serveMuxOptions...) @@ -106,10 +103,10 @@ func CreateGatewayWithPrefix( if err != nil { return nil, "", fmt.Errorf("failed to register grpc gateway: %w", err) } - return addInterceptors(runtimeMux, http1HostName, cookieHandler, cookieConfig, queries), g.GatewayPathPrefix(), nil + return addInterceptors(runtimeMux, http1HostName, accessInterceptor, queries), g.GatewayPathPrefix(), nil } -func CreateGateway(ctx context.Context, port uint16, http1HostName string, cookieHandler *http_utils.CookieHandler, cookieConfig *http_mw.AccessConfig) (*Gateway, error) { +func CreateGateway(ctx context.Context, port uint16, http1HostName string, accessInterceptor *http_mw.AccessInterceptor) (*Gateway, error) { connection, err := dial(ctx, port, []grpc.DialOption{ @@ -121,11 +118,10 @@ func CreateGateway(ctx context.Context, port uint16, http1HostName string, cooki } runtimeMux := runtime.NewServeMux(append(serveMuxOptions, runtime.WithHealthzEndpoint(healthpb.NewHealthClient(connection)))...) return &Gateway{ - mux: runtimeMux, - http1HostName: http1HostName, - connection: connection, - cookieHandler: cookieHandler, - cookieConfig: cookieConfig, + mux: runtimeMux, + http1HostName: http1HostName, + connection: connection, + accessInterceptor: accessInterceptor, }, nil } @@ -163,8 +159,7 @@ func dial(ctx context.Context, port uint16, opts []grpc.DialOption) (*grpc.Clien func addInterceptors( handler http.Handler, http1HostName string, - cookieHandler *http_utils.CookieHandler, - cookieConfig *http_mw.AccessConfig, + accessInterceptor *http_mw.AccessInterceptor, queries *query.Queries, ) http.Handler { handler = http_mw.CallDurationHandler(handler) @@ -174,7 +169,7 @@ func addInterceptors( handler = http_mw.DefaultTelemetryHandler(handler) // For some non-obvious reason, the exhaustedCookieInterceptor sends the SetCookie header // only if it follows the http_mw.DefaultTelemetryHandler - handler = exhaustedCookieInterceptor(handler, cookieHandler, cookieConfig, queries) + handler = exhaustedCookieInterceptor(handler, accessInterceptor, queries) handler = http_mw.DefaultMetricsHandler(handler) return handler } @@ -193,35 +188,32 @@ func http1Host(next http.Handler, http1HostName string) http.Handler { func exhaustedCookieInterceptor( next http.Handler, - cookieHandler *http_utils.CookieHandler, - cookieConfig *http_mw.AccessConfig, + accessInterceptor *http_mw.AccessInterceptor, queries *query.Queries, ) http.Handler { return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) { next.ServeHTTP(&cookieResponseWriter{ - ResponseWriter: writer, - cookieHandler: cookieHandler, - cookieConfig: cookieConfig, - request: request, - queries: queries, + ResponseWriter: writer, + accessInterceptor: accessInterceptor, + request: request, + queries: queries, }, request) }) } type cookieResponseWriter struct { http.ResponseWriter - cookieHandler *http_utils.CookieHandler - cookieConfig *http_mw.AccessConfig - request *http.Request - queries *query.Queries + accessInterceptor *http_mw.AccessInterceptor + request *http.Request + queries *query.Queries } func (r *cookieResponseWriter) WriteHeader(status int) { if status >= 200 && status < 300 { - http_mw.DeleteExhaustedCookie(r.cookieHandler, r.ResponseWriter, r.request, r.cookieConfig) + r.accessInterceptor.DeleteExhaustedCookie(r.ResponseWriter) } if status == http.StatusTooManyRequests { - http_mw.SetExhaustedCookie(r.cookieHandler, r.ResponseWriter, r.cookieConfig, r.request) + r.accessInterceptor.SetExhaustedCookie(r.ResponseWriter, r.request) } r.ResponseWriter.WriteHeader(status) } diff --git a/internal/api/grpc/settings/v2/settings_converter_test.go b/internal/api/grpc/settings/v2/settings_converter_test.go index 818bf64ffe..11ebc0f71c 100644 --- a/internal/api/grpc/settings/v2/settings_converter_test.go +++ b/internal/api/grpc/settings/v2/settings_converter_test.go @@ -11,38 +11,13 @@ import ( "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/types/known/durationpb" + "github.com/zitadel/zitadel/internal/api/grpc" "github.com/zitadel/zitadel/internal/domain" "github.com/zitadel/zitadel/internal/query" settings "github.com/zitadel/zitadel/pkg/grpc/settings/v2alpha" ) -var ignoreMessageTypes = map[protoreflect.FullName]bool{ - "google.protobuf.Duration": true, -} - -// allFieldsSet recusively checks if all values in a message -// have a non-zero value. -func allFieldsSet(t testing.TB, msg protoreflect.Message) { - md := msg.Descriptor() - name := md.FullName() - if ignoreMessageTypes[name] { - return - } - - fields := md.Fields() - - for i := 0; i < fields.Len(); i++ { - fd := fields.Get(i) - if !msg.Has(fd) { - t.Errorf("not all fields set in %q, missing %q", name, fd.Name()) - continue - } - - if fd.Kind() == protoreflect.MessageKind { - allFieldsSet(t, msg.Get(fd).Message()) - } - } -} +var ignoreTypes = []protoreflect.FullName{"google.protobuf.Duration"} func Test_loginSettingsToPb(t *testing.T) { arg := &query.LoginPolicy{ @@ -100,7 +75,7 @@ func Test_loginSettingsToPb(t *testing.T) { } got := loginSettingsToPb(arg) - allFieldsSet(t, got.ProtoReflect()) + grpc.AllFieldsSet(t, got.ProtoReflect(), ignoreTypes...) if !proto.Equal(got, want) { t.Errorf("loginSettingsToPb() =\n%v\nwant\n%v", got, want) } @@ -241,7 +216,7 @@ func Test_passwordSettingsToPb(t *testing.T) { } got := passwordSettingsToPb(arg) - allFieldsSet(t, got.ProtoReflect()) + grpc.AllFieldsSet(t, got.ProtoReflect(), ignoreTypes...) if !proto.Equal(got, want) { t.Errorf("passwordSettingsToPb() =\n%v\nwant\n%v", got, want) } @@ -295,7 +270,7 @@ func Test_brandingSettingsToPb(t *testing.T) { } got := brandingSettingsToPb(arg, "http://example.com") - allFieldsSet(t, got.ProtoReflect()) + grpc.AllFieldsSet(t, got.ProtoReflect(), ignoreTypes...) if !proto.Equal(got, want) { t.Errorf("brandingSettingsToPb() =\n%v\nwant\n%v", got, want) } @@ -315,7 +290,7 @@ func Test_domainSettingsToPb(t *testing.T) { ResourceOwnerType: settings.ResourceOwnerType_RESOURCE_OWNER_TYPE_INSTANCE, } got := domainSettingsToPb(arg) - allFieldsSet(t, got.ProtoReflect()) + grpc.AllFieldsSet(t, got.ProtoReflect(), ignoreTypes...) if !proto.Equal(got, want) { t.Errorf("domainSettingsToPb() =\n%v\nwant\n%v", got, want) } @@ -337,7 +312,7 @@ func Test_legalSettingsToPb(t *testing.T) { ResourceOwnerType: settings.ResourceOwnerType_RESOURCE_OWNER_TYPE_INSTANCE, } got := legalAndSupportSettingsToPb(arg) - allFieldsSet(t, got.ProtoReflect()) + grpc.AllFieldsSet(t, got.ProtoReflect(), ignoreTypes...) if !proto.Equal(got, want) { t.Errorf("legalSettingsToPb() =\n%v\nwant\n%v", got, want) } @@ -353,7 +328,7 @@ func Test_lockoutSettingsToPb(t *testing.T) { ResourceOwnerType: settings.ResourceOwnerType_RESOURCE_OWNER_TYPE_INSTANCE, } got := lockoutSettingsToPb(arg) - allFieldsSet(t, got.ProtoReflect()) + grpc.AllFieldsSet(t, got.ProtoReflect(), ignoreTypes...) if !proto.Equal(got, want) { t.Errorf("lockoutSettingsToPb() =\n%v\nwant\n%v", got, want) } @@ -387,7 +362,7 @@ func Test_identityProvidersToPb(t *testing.T) { got := identityProvidersToPb(arg) require.Len(t, got, len(got)) for i, v := range got { - allFieldsSet(t, v.ProtoReflect()) + grpc.AllFieldsSet(t, v.ProtoReflect(), ignoreTypes...) if !proto.Equal(v, want[i]) { t.Errorf("identityProvidersToPb() =\n%v\nwant\n%v", got, want) } diff --git a/internal/api/grpc/user/v2/passkey.go b/internal/api/grpc/user/v2/passkey.go new file mode 100644 index 0000000000..eb1b276f8f --- /dev/null +++ b/internal/api/grpc/user/v2/passkey.go @@ -0,0 +1,104 @@ +package user + +import ( + "context" + + "github.com/zitadel/zitadel/internal/api/authz" + "github.com/zitadel/zitadel/internal/api/grpc/object/v2" + "github.com/zitadel/zitadel/internal/domain" + caos_errs "github.com/zitadel/zitadel/internal/errors" + user "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha" +) + +func (s *Server) RegisterPasskey(ctx context.Context, req *user.RegisterPasskeyRequest) (resp *user.RegisterPasskeyResponse, err error) { + var ( + resourceOwner = authz.GetCtxData(ctx).ResourceOwner + authenticator = passkeyAuthenticatorToDomain(req.GetAuthenticator()) + ) + if code := req.GetCode(); code != nil { + return passkeyRegistrationDetailsToPb( + s.command.RegisterUserPasskeyWithCode(ctx, req.GetUserId(), resourceOwner, authenticator, code.Id, code.Code, s.userCodeAlg), + ) + } + return passkeyRegistrationDetailsToPb( + s.command.RegisterUserPasskey(ctx, req.GetUserId(), resourceOwner, authenticator), + ) +} + +func passkeyAuthenticatorToDomain(pa user.PasskeyAuthenticator) domain.AuthenticatorAttachment { + switch pa { + case user.PasskeyAuthenticator_PASSKEY_AUTHENTICATOR_UNSPECIFIED: + return domain.AuthenticatorAttachmentUnspecified + case user.PasskeyAuthenticator_PASSKEY_AUTHENTICATOR_PLATFORM: + return domain.AuthenticatorAttachmentPlattform + case user.PasskeyAuthenticator_PASSKEY_AUTHENTICATOR_CROSS_PLATFORM: + return domain.AuthenticatorAttachmentCrossPlattform + default: + return domain.AuthenticatorAttachmentUnspecified + } +} + +func passkeyRegistrationDetailsToPb(details *domain.PasskeyRegistrationDetails, err error) (*user.RegisterPasskeyResponse, error) { + if err != nil { + return nil, err + } + return &user.RegisterPasskeyResponse{ + Details: object.DomainToDetailsPb(details.ObjectDetails), + PasskeyId: details.PasskeyID, + PublicKeyCredentialCreationOptions: details.PublicKeyCredentialCreationOptions, + }, nil +} + +func (s *Server) VerifyPasskeyRegistration(ctx context.Context, req *user.VerifyPasskeyRegistrationRequest) (*user.VerifyPasskeyRegistrationResponse, error) { + resourceOwner := authz.GetCtxData(ctx).ResourceOwner + objectDetails, err := s.command.HumanHumanPasswordlessSetup(ctx, req.GetUserId(), resourceOwner, req.GetPasskeyName(), "", req.GetPublicKeyCredential()) + if err != nil { + return nil, err + } + return &user.VerifyPasskeyRegistrationResponse{ + Details: object.DomainToDetailsPb(objectDetails), + }, nil +} + +func (s *Server) CreatePasskeyRegistrationLink(ctx context.Context, req *user.CreatePasskeyRegistrationLinkRequest) (resp *user.CreatePasskeyRegistrationLinkResponse, err error) { + resourceOwner := authz.GetCtxData(ctx).ResourceOwner + + switch medium := req.Medium.(type) { + case nil: + return passkeyDetailsToPb( + s.command.AddUserPasskeyCode(ctx, req.GetUserId(), resourceOwner, s.userCodeAlg), + ) + case *user.CreatePasskeyRegistrationLinkRequest_SendLink: + return passkeyDetailsToPb( + s.command.AddUserPasskeyCodeURLTemplate(ctx, req.GetUserId(), resourceOwner, s.userCodeAlg, medium.SendLink.GetUrlTemplate()), + ) + case *user.CreatePasskeyRegistrationLinkRequest_ReturnCode: + return passkeyCodeDetailsToPb( + s.command.AddUserPasskeyCodeReturn(ctx, req.GetUserId(), resourceOwner, s.userCodeAlg), + ) + default: + return nil, caos_errs.ThrowUnimplementedf(nil, "USERv2-gaD8y", "verification oneOf %T in method CreatePasskeyRegistrationLink not implemented", medium) + } +} + +func passkeyDetailsToPb(details *domain.ObjectDetails, err error) (*user.CreatePasskeyRegistrationLinkResponse, error) { + if err != nil { + return nil, err + } + return &user.CreatePasskeyRegistrationLinkResponse{ + Details: object.DomainToDetailsPb(details), + }, nil +} + +func passkeyCodeDetailsToPb(details *domain.PasskeyCodeDetails, err error) (*user.CreatePasskeyRegistrationLinkResponse, error) { + if err != nil { + return nil, err + } + return &user.CreatePasskeyRegistrationLinkResponse{ + Details: object.DomainToDetailsPb(details.ObjectDetails), + Code: &user.PasskeyRegistrationCode{ + Id: details.CodeID, + Code: details.Code, + }, + }, nil +} diff --git a/internal/api/grpc/user/v2/passkey_integration_test.go b/internal/api/grpc/user/v2/passkey_integration_test.go new file mode 100644 index 0000000000..623b2544fd --- /dev/null +++ b/internal/api/grpc/user/v2/passkey_integration_test.go @@ -0,0 +1,309 @@ +//go:build integration + +package user_test + +import ( + "context" + "testing" + + "github.com/muhlemmer/gu" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/zitadel/zitadel/internal/integration" + "github.com/zitadel/zitadel/internal/webauthn" + object "github.com/zitadel/zitadel/pkg/grpc/object/v2alpha" + user "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha" +) + +func TestServer_RegisterPasskey(t *testing.T) { + userID := createHumanUser(t).GetUserId() + reg, err := Client.CreatePasskeyRegistrationLink(CTX, &user.CreatePasskeyRegistrationLinkRequest{ + UserId: userID, + Medium: &user.CreatePasskeyRegistrationLinkRequest_ReturnCode{}, + }) + require.NoError(t, err) + client := webauthn.NewClient(Tester.Config.WebAuthNName, Tester.Config.ExternalDomain, "https://"+Tester.Host()) + + type args struct { + ctx context.Context + req *user.RegisterPasskeyRequest + } + tests := []struct { + name string + args args + want *user.RegisterPasskeyResponse + wantErr bool + }{ + { + name: "missing user id", + args: args{ + ctx: CTX, + req: &user.RegisterPasskeyRequest{}, + }, + wantErr: true, + }, + { + name: "register code", + args: args{ + ctx: CTX, + req: &user.RegisterPasskeyRequest{ + UserId: userID, + Code: reg.GetCode(), + Authenticator: user.PasskeyAuthenticator_PASSKEY_AUTHENTICATOR_PLATFORM, + }, + }, + want: &user.RegisterPasskeyResponse{ + Details: &object.Details{ + ResourceOwner: Tester.Organisation.ID, + }, + }, + }, + { + name: "reuse code (not allowed)", + args: args{ + ctx: CTX, + req: &user.RegisterPasskeyRequest{ + UserId: userID, + Code: reg.GetCode(), + Authenticator: user.PasskeyAuthenticator_PASSKEY_AUTHENTICATOR_PLATFORM, + }, + }, + wantErr: true, + }, + { + name: "wrong code", + args: args{ + ctx: CTX, + req: &user.RegisterPasskeyRequest{ + UserId: userID, + Code: &user.PasskeyRegistrationCode{ + Id: reg.GetCode().GetId(), + Code: "foobar", + }, + Authenticator: user.PasskeyAuthenticator_PASSKEY_AUTHENTICATOR_CROSS_PLATFORM, + }, + }, + wantErr: true, + }, + { + name: "user mismatch", + args: args{ + ctx: CTX, + req: &user.RegisterPasskeyRequest{ + UserId: userID, + }, + }, + wantErr: true, + }, + /* TODO after we are able to obtain a Bearer token for a human user + { + name: "human user", + args: args{ + ctx: CTX, + req: &user.RegisterPasskeyRequest{ + UserId: humanUserID, + }, + }, + want: &user.RegisterPasskeyResponse{ + Details: &object.Details{ + ResourceOwner: Tester.Organisation.ID, + }, + }, + }, + */ + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := Client.RegisterPasskey(tt.args.ctx, tt.args.req) + if tt.wantErr { + require.Error(t, err) + return + } + require.NoError(t, err) + require.NotNil(t, got) + integration.AssertDetails(t, tt.want, got) + if tt.want != nil { + assert.NotEmpty(t, got.GetPasskeyId()) + assert.NotEmpty(t, got.GetPublicKeyCredentialCreationOptions()) + _, err := client.CreateAttestationResponse(got.GetPublicKeyCredentialCreationOptions()) + require.NoError(t, err) + } + }) + } +} + +func TestServer_VerifyPasskeyRegistration(t *testing.T) { + userID := createHumanUser(t).GetUserId() + reg, err := Client.CreatePasskeyRegistrationLink(CTX, &user.CreatePasskeyRegistrationLinkRequest{ + UserId: userID, + Medium: &user.CreatePasskeyRegistrationLinkRequest_ReturnCode{}, + }) + require.NoError(t, err) + pkr, err := Client.RegisterPasskey(CTX, &user.RegisterPasskeyRequest{ + UserId: userID, + Code: reg.GetCode(), + }) + require.NoError(t, err) + require.NotEmpty(t, pkr.GetPasskeyId()) + require.NotEmpty(t, pkr.GetPublicKeyCredentialCreationOptions()) + + client := webauthn.NewClient(Tester.Config.WebAuthNName, Tester.Config.ExternalDomain, "https://"+Tester.Host()) + attestationResponse, err := client.CreateAttestationResponse(pkr.GetPublicKeyCredentialCreationOptions()) + require.NoError(t, err) + + type args struct { + ctx context.Context + req *user.VerifyPasskeyRegistrationRequest + } + tests := []struct { + name string + args args + want *user.VerifyPasskeyRegistrationResponse + wantErr bool + }{ + { + name: "missing user id", + args: args{ + ctx: CTX, + req: &user.VerifyPasskeyRegistrationRequest{ + PasskeyId: pkr.GetPasskeyId(), + PublicKeyCredential: []byte(attestationResponse), + PasskeyName: "nice name", + }, + }, + wantErr: true, + }, + { + name: "success", + args: args{ + ctx: CTX, + req: &user.VerifyPasskeyRegistrationRequest{ + UserId: userID, + PasskeyId: pkr.GetPasskeyId(), + PublicKeyCredential: attestationResponse, + PasskeyName: "nice name", + }, + }, + want: &user.VerifyPasskeyRegistrationResponse{ + Details: &object.Details{ + ResourceOwner: Tester.Organisation.ID, + }, + }, + }, + { + name: "wrong credential", + args: args{ + ctx: CTX, + req: &user.VerifyPasskeyRegistrationRequest{ + UserId: userID, + PasskeyId: pkr.GetPasskeyId(), + PublicKeyCredential: []byte("attestationResponseattestationResponseattestationResponse"), + PasskeyName: "nice name", + }, + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := Client.VerifyPasskeyRegistration(tt.args.ctx, tt.args.req) + if tt.wantErr { + require.Error(t, err) + return + } + require.NoError(t, err) + require.NotNil(t, got) + integration.AssertDetails(t, tt.want, got) + }) + } +} + +func TestServer_CreatePasskeyRegistrationLink(t *testing.T) { + userID := createHumanUser(t).GetUserId() + + type args struct { + ctx context.Context + req *user.CreatePasskeyRegistrationLinkRequest + } + tests := []struct { + name string + args args + want *user.CreatePasskeyRegistrationLinkResponse + wantCode bool + wantErr bool + }{ + { + name: "missing user id", + args: args{ + ctx: CTX, + req: &user.CreatePasskeyRegistrationLinkRequest{}, + }, + wantErr: true, + }, + { + name: "send default mail", + args: args{ + ctx: CTX, + req: &user.CreatePasskeyRegistrationLinkRequest{ + UserId: userID, + }, + }, + want: &user.CreatePasskeyRegistrationLinkResponse{ + Details: &object.Details{ + ResourceOwner: Tester.Organisation.ID, + }, + }, + }, + { + name: "send custom url", + args: args{ + ctx: CTX, + req: &user.CreatePasskeyRegistrationLinkRequest{ + UserId: userID, + Medium: &user.CreatePasskeyRegistrationLinkRequest_SendLink{ + SendLink: &user.SendPasskeyRegistrationLink{ + UrlTemplate: gu.Ptr("https://example.com/passkey/register?userID={{.UserID}}&orgID={{.OrgID}}&codeID={{.CodeID}}&code={{.Code}}"), + }, + }, + }, + }, + want: &user.CreatePasskeyRegistrationLinkResponse{ + Details: &object.Details{ + ResourceOwner: Tester.Organisation.ID, + }, + }, + }, + { + name: "return code", + args: args{ + ctx: CTX, + req: &user.CreatePasskeyRegistrationLinkRequest{ + UserId: userID, + Medium: &user.CreatePasskeyRegistrationLinkRequest_ReturnCode{}, + }, + }, + want: &user.CreatePasskeyRegistrationLinkResponse{ + Details: &object.Details{ + ResourceOwner: Tester.Organisation.ID, + }, + }, + wantCode: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := Client.CreatePasskeyRegistrationLink(tt.args.ctx, tt.args.req) + if tt.wantErr { + require.Error(t, err) + return + } + require.NoError(t, err) + require.NotNil(t, got) + integration.AssertDetails(t, tt.want, got) + if tt.wantCode { + assert.NotEmpty(t, got.GetCode().GetId()) + assert.NotEmpty(t, got.GetCode().GetId()) + } + }) + } +} diff --git a/internal/api/grpc/user/v2/passkey_test.go b/internal/api/grpc/user/v2/passkey_test.go new file mode 100644 index 0000000000..d1934c3ca2 --- /dev/null +++ b/internal/api/grpc/user/v2/passkey_test.go @@ -0,0 +1,210 @@ +package user + +import ( + "io" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "google.golang.org/protobuf/types/known/timestamppb" + + "github.com/zitadel/zitadel/internal/api/grpc" + "github.com/zitadel/zitadel/internal/domain" + object "github.com/zitadel/zitadel/pkg/grpc/object/v2alpha" + user "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha" +) + +func Test_passkeyAuthenticatorToDomain(t *testing.T) { + tests := []struct { + pa user.PasskeyAuthenticator + want domain.AuthenticatorAttachment + }{ + { + pa: user.PasskeyAuthenticator_PASSKEY_AUTHENTICATOR_UNSPECIFIED, + want: domain.AuthenticatorAttachmentUnspecified, + }, + { + pa: user.PasskeyAuthenticator_PASSKEY_AUTHENTICATOR_PLATFORM, + want: domain.AuthenticatorAttachmentPlattform, + }, + { + pa: user.PasskeyAuthenticator_PASSKEY_AUTHENTICATOR_CROSS_PLATFORM, + want: domain.AuthenticatorAttachmentCrossPlattform, + }, + { + pa: 999, + want: domain.AuthenticatorAttachmentUnspecified, + }, + } + for _, tt := range tests { + t.Run(tt.pa.String(), func(t *testing.T) { + got := passkeyAuthenticatorToDomain(tt.pa) + assert.Equal(t, tt.want, got) + }) + } +} + +func Test_passkeyRegistrationDetailsToPb(t *testing.T) { + type args struct { + details *domain.PasskeyRegistrationDetails + err error + } + tests := []struct { + name string + args args + want *user.RegisterPasskeyResponse + }{ + { + name: "an error", + args: args{ + details: nil, + err: io.ErrClosedPipe, + }, + }, + { + name: "ok", + args: args{ + details: &domain.PasskeyRegistrationDetails{ + ObjectDetails: &domain.ObjectDetails{ + Sequence: 22, + EventDate: time.Unix(3000, 22), + ResourceOwner: "me", + }, + PasskeyID: "123", + PublicKeyCredentialCreationOptions: []byte{1, 2, 3}, + }, + err: nil, + }, + want: &user.RegisterPasskeyResponse{ + Details: &object.Details{ + Sequence: 22, + ChangeDate: ×tamppb.Timestamp{ + Seconds: 3000, + Nanos: 22, + }, + ResourceOwner: "me", + }, + PasskeyId: "123", + PublicKeyCredentialCreationOptions: []byte{1, 2, 3}, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := passkeyRegistrationDetailsToPb(tt.args.details, tt.args.err) + require.ErrorIs(t, err, tt.args.err) + assert.Equal(t, tt.want, got) + if tt.want != nil { + grpc.AllFieldsSet(t, got.ProtoReflect()) + } + }) + } +} + +func Test_passkeyDetailsToPb(t *testing.T) { + type args struct { + details *domain.ObjectDetails + err error + } + tests := []struct { + name string + args args + want *user.CreatePasskeyRegistrationLinkResponse + }{ + { + name: "an error", + args: args{ + details: nil, + err: io.ErrClosedPipe, + }, + }, + { + name: "ok", + args: args{ + details: &domain.ObjectDetails{ + Sequence: 22, + EventDate: time.Unix(3000, 22), + ResourceOwner: "me", + }, + err: nil, + }, + want: &user.CreatePasskeyRegistrationLinkResponse{ + Details: &object.Details{ + Sequence: 22, + ChangeDate: ×tamppb.Timestamp{ + Seconds: 3000, + Nanos: 22, + }, + ResourceOwner: "me", + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := passkeyDetailsToPb(tt.args.details, tt.args.err) + require.ErrorIs(t, err, tt.args.err) + assert.Equal(t, tt.want, got) + }) + } +} + +func Test_passkeyCodeDetailsToPb(t *testing.T) { + type args struct { + details *domain.PasskeyCodeDetails + err error + } + tests := []struct { + name string + args args + want *user.CreatePasskeyRegistrationLinkResponse + }{ + { + name: "an error", + args: args{ + details: nil, + err: io.ErrClosedPipe, + }, + }, + { + name: "ok", + args: args{ + details: &domain.PasskeyCodeDetails{ + ObjectDetails: &domain.ObjectDetails{ + Sequence: 22, + EventDate: time.Unix(3000, 22), + ResourceOwner: "me", + }, + CodeID: "123", + Code: "456", + }, + err: nil, + }, + want: &user.CreatePasskeyRegistrationLinkResponse{ + Details: &object.Details{ + Sequence: 22, + ChangeDate: ×tamppb.Timestamp{ + Seconds: 3000, + Nanos: 22, + }, + ResourceOwner: "me", + }, + Code: &user.PasskeyRegistrationCode{ + Id: "123", + Code: "456", + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := passkeyCodeDetailsToPb(tt.args.details, tt.args.err) + require.ErrorIs(t, err, tt.args.err) + assert.Equal(t, tt.want, got) + if tt.want != nil { + grpc.AllFieldsSet(t, got.ProtoReflect()) + } + }) + } +} diff --git a/internal/api/grpc/user/v2/server.go b/internal/api/grpc/user/v2/server.go index d81d51ff23..13ee611776 100644 --- a/internal/api/grpc/user/v2/server.go +++ b/internal/api/grpc/user/v2/server.go @@ -1,6 +1,8 @@ package user import ( + "context" + "google.golang.org/grpc" "github.com/zitadel/zitadel/internal/api/authz" @@ -18,15 +20,25 @@ type Server struct { command *command.Commands query *query.Queries userCodeAlg crypto.EncryptionAlgorithm + idpAlg crypto.EncryptionAlgorithm + idpCallback func(ctx context.Context) string } type Config struct{} -func CreateServer(command *command.Commands, query *query.Queries, userCodeAlg crypto.EncryptionAlgorithm) *Server { +func CreateServer( + command *command.Commands, + query *query.Queries, + userCodeAlg crypto.EncryptionAlgorithm, + idpAlg crypto.EncryptionAlgorithm, + idpCallback func(ctx context.Context) string, +) *Server { return &Server{ command: command, query: query, userCodeAlg: userCodeAlg, + idpAlg: idpAlg, + idpCallback: idpCallback, } } diff --git a/internal/api/grpc/user/v2/user.go b/internal/api/grpc/user/v2/user.go index 4388f69f99..97e13e05c5 100644 --- a/internal/api/grpc/user/v2/user.go +++ b/internal/api/grpc/user/v2/user.go @@ -2,15 +2,19 @@ package user import ( "context" + "encoding/base64" "io" "golang.org/x/text/language" + "google.golang.org/protobuf/types/known/timestamppb" "github.com/zitadel/zitadel/internal/api/authz" "github.com/zitadel/zitadel/internal/api/grpc/object/v2" "github.com/zitadel/zitadel/internal/command" + "github.com/zitadel/zitadel/internal/crypto" "github.com/zitadel/zitadel/internal/domain" "github.com/zitadel/zitadel/internal/errors" + object_pb "github.com/zitadel/zitadel/pkg/grpc/object/v2alpha" user "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha" ) @@ -56,6 +60,14 @@ func addUserRequestToAddHuman(req *user.AddHumanUserRequest) (*command.AddHuman, Value: metadataEntry.GetValue(), } } + links := make([]*command.AddLink, len(req.GetIdpLinks())) + for i, link := range req.GetIdpLinks() { + links[i] = &command.AddLink{ + IDPID: link.GetIdpId(), + IDPExternalID: link.GetIdpExternalId(), + DisplayName: link.GetDisplayName(), + } + } return &command.AddHuman{ ID: req.GetUserId(), Username: username, @@ -76,9 +88,9 @@ func addUserRequestToAddHuman(req *user.AddHumanUserRequest) (*command.AddHuman, BcryptedPassword: bcryptedPassword, PasswordChangeRequired: passwordChangeRequired, Passwordless: false, - ExternalIDP: false, Register: false, Metadata: metadata, + Links: links, }, nil } @@ -107,3 +119,95 @@ func hashedPasswordToCommand(hashed *user.HashedPassword) (string, error) { } return hashed.GetHash(), nil } + +func (s *Server) AddIDPLink(ctx context.Context, req *user.AddIDPLinkRequest) (_ *user.AddIDPLinkResponse, err error) { + orgID := authz.GetCtxData(ctx).OrgID + details, err := s.command.AddUserIDPLink(ctx, req.UserId, orgID, &domain.UserIDPLink{ + IDPConfigID: req.GetIdpLink().GetIdpId(), + ExternalUserID: req.GetIdpLink().GetIdpExternalId(), + DisplayName: req.GetIdpLink().GetDisplayName(), + }) + if err != nil { + return nil, err + } + return &user.AddIDPLinkResponse{ + Details: object.DomainToDetailsPb(details), + }, nil +} + +func (s *Server) StartIdentityProviderFlow(ctx context.Context, req *user.StartIdentityProviderFlowRequest) (_ *user.StartIdentityProviderFlowResponse, err error) { + id, details, err := s.command.CreateIntent(ctx, req.GetIdpId(), req.GetSuccessUrl(), req.GetFailureUrl(), authz.GetCtxData(ctx).OrgID) + if err != nil { + return nil, err + } + authURL, err := s.command.AuthURLFromProvider(ctx, req.GetIdpId(), id, s.idpCallback(ctx)) + if err != nil { + return nil, err + } + return &user.StartIdentityProviderFlowResponse{ + Details: object.DomainToDetailsPb(details), + NextStep: &user.StartIdentityProviderFlowResponse_AuthUrl{AuthUrl: authURL}, + }, nil +} + +func (s *Server) RetrieveIdentityProviderInformation(ctx context.Context, req *user.RetrieveIdentityProviderInformationRequest) (_ *user.RetrieveIdentityProviderInformationResponse, err error) { + intent, err := s.command.GetIntentWriteModel(ctx, req.GetIntentId(), authz.GetCtxData(ctx).OrgID) + if err != nil { + return nil, err + } + if err := s.checkIntentToken(req.GetToken(), intent.AggregateID); err != nil { + return nil, err + } + if intent.State != domain.IDPIntentStateSucceeded { + return nil, errors.ThrowPreconditionFailed(nil, "IDP-Hk38e", "Errors.Intent.NotSucceeded") + } + return intentToIDPInformationPb(intent, s.idpAlg) +} + +func intentToIDPInformationPb(intent *command.IDPIntentWriteModel, alg crypto.EncryptionAlgorithm) (_ *user.RetrieveIdentityProviderInformationResponse, err error) { + var idToken *string + if intent.IDPIDToken != "" { + idToken = &intent.IDPIDToken + } + var accessToken string + if intent.IDPAccessToken != nil { + accessToken, err = crypto.DecryptString(intent.IDPAccessToken, alg) + if err != nil { + return nil, err + } + } + return &user.RetrieveIdentityProviderInformationResponse{ + Details: &object_pb.Details{ + Sequence: intent.ProcessedSequence, + ChangeDate: timestamppb.New(intent.ChangeDate), + ResourceOwner: intent.ResourceOwner, + }, + IdpInformation: &user.IDPInformation{ + Access: &user.IDPInformation_Oauth{ + Oauth: &user.IDPOAuthAccessInformation{ + AccessToken: accessToken, + IdToken: idToken, + }, + }, + IdpInformation: intent.IDPUser, + }, + }, nil +} + +func (s *Server) checkIntentToken(token string, intentID string) error { + if token == "" { + return errors.ThrowPermissionDenied(nil, "IDP-Sfefs", "Errors.Intent.InvalidToken") + } + data, err := base64.RawURLEncoding.DecodeString(token) + if err != nil { + return errors.ThrowPermissionDenied(err, "IDP-Swg31", "Errors.Intent.InvalidToken") + } + decryptedToken, err := s.idpAlg.Decrypt(data, s.idpAlg.EncryptionKeyID()) + if err != nil { + return errors.ThrowPermissionDenied(err, "IDP-Sf4gt", "Errors.Intent.InvalidToken") + } + if string(decryptedToken) != intentID { + return errors.ThrowPermissionDenied(nil, "IDP-dkje3", "Errors.Intent.InvalidToken") + } + return nil +} diff --git a/internal/api/grpc/user/v2/user_integration_test.go b/internal/api/grpc/user/v2/user_integration_test.go index c389ee073a..601e6ee6b3 100644 --- a/internal/api/grpc/user/v2/user_integration_test.go +++ b/internal/api/grpc/user/v2/user_integration_test.go @@ -6,16 +6,24 @@ import ( "context" "fmt" "os" + "strings" "testing" "time" "github.com/muhlemmer/gu" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/zitadel/oidc/v2/pkg/oidc" + "golang.org/x/oauth2" + "google.golang.org/protobuf/types/known/timestamppb" + + "github.com/zitadel/zitadel/internal/api/authz" + "github.com/zitadel/zitadel/internal/command" + "github.com/zitadel/zitadel/internal/idp/providers/oauth" "github.com/zitadel/zitadel/internal/integration" + "github.com/zitadel/zitadel/internal/repository/idp" object "github.com/zitadel/zitadel/pkg/grpc/object/v2alpha" user "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha" - "google.golang.org/protobuf/types/known/timestamppb" ) var ( @@ -39,7 +47,60 @@ func TestMain(m *testing.M) { }()) } +func createProvider(t *testing.T) string { + ctx := authz.WithInstance(context.Background(), Tester.Instance) + id, _, err := Tester.Commands.AddOrgGenericOAuthProvider(ctx, Tester.Organisation.ID, command.GenericOAuthProvider{ + "idp", + "clientID", + "clientSecret", + "https://example.com/oauth/v2/authorize", + "https://example.com/oauth/v2/token", + "https://api.example.com/user", + []string{"openid", "profile", "email"}, + "id", + idp.Options{ + IsLinkingAllowed: true, + IsCreationAllowed: true, + IsAutoCreation: true, + IsAutoUpdate: true, + }, + }) + require.NoError(t, err) + return id +} + +func createIntent(t *testing.T, idpID string) string { + ctx := authz.WithInstance(context.Background(), Tester.Instance) + id, _, err := Tester.Commands.CreateIntent(ctx, idpID, "https://example.com/success", "https://example.com/failure", Tester.Organisation.ID) + require.NoError(t, err) + return id +} + +func createSuccessfulIntent(t *testing.T, idpID string) (string, string, time.Time, uint64) { + ctx := authz.WithInstance(context.Background(), Tester.Instance) + intentID := createIntent(t, idpID) + writeModel, err := Tester.Commands.GetIntentWriteModel(ctx, intentID, Tester.Organisation.ID) + require.NoError(t, err) + idpUser := &oauth.UserMapper{ + RawInfo: map[string]interface{}{ + "id": "id", + }, + } + idpSession := &oauth.Session{ + Tokens: &oidc.Tokens[*oidc.IDTokenClaims]{ + Token: &oauth2.Token{ + AccessToken: "accessToken", + }, + IDToken: "idToken", + }, + } + token, err := Tester.Commands.SucceedIDPIntent(ctx, writeModel, idpUser, idpSession, "") + require.NoError(t, err) + return intentID, token, writeModel.ChangeDate, writeModel.ProcessedSequence +} + func TestServer_AddHumanUser(t *testing.T) { + idpID := createProvider(t) type args struct { ctx context.Context req *user.AddHumanUserRequest @@ -287,6 +348,105 @@ func TestServer_AddHumanUser(t *testing.T) { }, wantErr: true, }, + { + name: "missing idp", + args: args{ + CTX, + &user.AddHumanUserRequest{ + Organisation: &object.Organisation{ + Org: &object.Organisation_OrgId{ + OrgId: Tester.Organisation.ID, + }, + }, + Profile: &user.SetHumanProfile{ + FirstName: "Donald", + LastName: "Duck", + NickName: gu.Ptr("Dukkie"), + DisplayName: gu.Ptr("Donald Duck"), + PreferredLanguage: gu.Ptr("en"), + Gender: user.Gender_GENDER_DIVERSE.Enum(), + }, + Email: &user.SetHumanEmail{ + Email: "livio@zitadel.com", + Verification: &user.SetHumanEmail_IsVerified{ + IsVerified: true, + }, + }, + Metadata: []*user.SetMetadataEntry{ + { + Key: "somekey", + Value: []byte("somevalue"), + }, + }, + PasswordType: &user.AddHumanUserRequest_Password{ + Password: &user.Password{ + Password: "DifficultPW666!", + ChangeRequired: false, + }, + }, + IdpLinks: []*user.IDPLink{ + { + IdpId: "idpID", + IdpExternalId: "externalID", + DisplayName: "displayName", + }, + }, + }, + }, + wantErr: true, + }, + { + name: "with idp", + args: args{ + CTX, + &user.AddHumanUserRequest{ + Organisation: &object.Organisation{ + Org: &object.Organisation_OrgId{ + OrgId: Tester.Organisation.ID, + }, + }, + Profile: &user.SetHumanProfile{ + FirstName: "Donald", + LastName: "Duck", + NickName: gu.Ptr("Dukkie"), + DisplayName: gu.Ptr("Donald Duck"), + PreferredLanguage: gu.Ptr("en"), + Gender: user.Gender_GENDER_DIVERSE.Enum(), + }, + Email: &user.SetHumanEmail{ + Email: "livio@zitadel.com", + Verification: &user.SetHumanEmail_IsVerified{ + IsVerified: true, + }, + }, + Metadata: []*user.SetMetadataEntry{ + { + Key: "somekey", + Value: []byte("somevalue"), + }, + }, + PasswordType: &user.AddHumanUserRequest_Password{ + Password: &user.Password{ + Password: "DifficultPW666!", + ChangeRequired: false, + }, + }, + IdpLinks: []*user.IDPLink{ + { + IdpId: idpID, + IdpExternalId: "externalID", + DisplayName: "displayName", + }, + }, + }, + }, + want: &user.AddHumanUserResponse{ + Details: &object.Details{ + ChangeDate: timestamppb.Now(), + ResourceOwner: Tester.Organisation.ID, + }, + }, + }, } for i, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -315,3 +475,226 @@ func TestServer_AddHumanUser(t *testing.T) { }) } } + +func TestServer_AddIDPLink(t *testing.T) { + idpID := createProvider(t) + type args struct { + ctx context.Context + req *user.AddIDPLinkRequest + } + tests := []struct { + name string + args args + want *user.AddIDPLinkResponse + wantErr bool + }{ + { + name: "user does not exist", + args: args{ + CTX, + &user.AddIDPLinkRequest{ + UserId: "userID", + IdpLink: &user.IDPLink{ + IdpId: idpID, + IdpExternalId: "externalID", + DisplayName: "displayName", + }, + }, + }, + want: nil, + wantErr: true, + }, + { + name: "idp does not exist", + args: args{ + CTX, + &user.AddIDPLinkRequest{ + UserId: Tester.Users[integration.OrgOwner].ID, + IdpLink: &user.IDPLink{ + IdpId: "idpID", + IdpExternalId: "externalID", + DisplayName: "displayName", + }, + }, + }, + want: nil, + wantErr: true, + }, + { + name: "add link", + args: args{ + CTX, + &user.AddIDPLinkRequest{ + UserId: Tester.Users[integration.OrgOwner].ID, + IdpLink: &user.IDPLink{ + IdpId: idpID, + IdpExternalId: "externalID", + DisplayName: "displayName", + }, + }, + }, + want: &user.AddIDPLinkResponse{ + Details: &object.Details{ + ChangeDate: timestamppb.Now(), + ResourceOwner: Tester.Organisation.ID, + }, + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := Client.AddIDPLink(tt.args.ctx, tt.args.req) + if tt.wantErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + + integration.AssertDetails(t, tt.want, got) + }) + } +} + +func TestServer_StartIdentityProviderFlow(t *testing.T) { + idpID := createProvider(t) + type args struct { + ctx context.Context + req *user.StartIdentityProviderFlowRequest + } + tests := []struct { + name string + args args + want *user.StartIdentityProviderFlowResponse + wantErr bool + }{ + { + name: "missing urls", + args: args{ + CTX, + &user.StartIdentityProviderFlowRequest{ + IdpId: idpID, + }, + }, + want: nil, + wantErr: true, + }, + { + name: "next step auth url", + args: args{ + CTX, + &user.StartIdentityProviderFlowRequest{ + IdpId: idpID, + SuccessUrl: "https://example.com/success", + FailureUrl: "https://example.com/failure", + }, + }, + want: &user.StartIdentityProviderFlowResponse{ + Details: &object.Details{ + ChangeDate: timestamppb.Now(), + ResourceOwner: Tester.Organisation.ID, + }, + NextStep: &user.StartIdentityProviderFlowResponse_AuthUrl{ + AuthUrl: "https://example.com/oauth/v2/authorize?client_id=clientID&prompt=select_account&redirect_uri=https%3A%2F%2Flocalhost%3A8080%2Fidps%2Fcallback&response_type=code&scope=openid+profile+email&state=", + }, + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := Client.StartIdentityProviderFlow(tt.args.ctx, tt.args.req) + if tt.wantErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + + if nextStep := tt.want.GetNextStep(); nextStep != nil { + if !strings.HasPrefix(got.GetAuthUrl(), tt.want.GetAuthUrl()) { + assert.Failf(t, "auth url does not match", "expected: %s, but got: %s", tt.want.GetAuthUrl(), got.GetAuthUrl()) + } + } + integration.AssertDetails(t, tt.want, got) + }) + } +} + +func TestServer_RetrieveIdentityProviderInformation(t *testing.T) { + idpID := createProvider(t) + intentID := createIntent(t, idpID) + successfulID, token, changeDate, sequence := createSuccessfulIntent(t, idpID) + type args struct { + ctx context.Context + req *user.RetrieveIdentityProviderInformationRequest + } + tests := []struct { + name string + args args + want *user.RetrieveIdentityProviderInformationResponse + wantErr bool + }{ + { + name: "failed intent", + args: args{ + CTX, + &user.RetrieveIdentityProviderInformationRequest{ + IntentId: intentID, + Token: "", + }, + }, + wantErr: true, + }, + { + name: "wrong token", + args: args{ + CTX, + &user.RetrieveIdentityProviderInformationRequest{ + IntentId: successfulID, + Token: "wrong token", + }, + }, + wantErr: true, + }, + { + name: "retrieve successful intent", + args: args{ + CTX, + &user.RetrieveIdentityProviderInformationRequest{ + IntentId: successfulID, + Token: token, + }, + }, + want: &user.RetrieveIdentityProviderInformationResponse{ + Details: &object.Details{ + ChangeDate: timestamppb.New(changeDate), + ResourceOwner: Tester.Organisation.ID, + Sequence: sequence, + }, + IdpInformation: &user.IDPInformation{ + Access: &user.IDPInformation_Oauth{ + Oauth: &user.IDPOAuthAccessInformation{ + AccessToken: "accessToken", + IdToken: gu.Ptr("idToken"), + }, + }, + IdpInformation: []byte(`{"RawInfo":{"id":"id"}}`), + }, + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := Client.RetrieveIdentityProviderInformation(tt.args.ctx, tt.args.req) + if tt.wantErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + + require.Equal(t, tt.want.GetDetails(), got.GetDetails()) + require.Equal(t, tt.want.GetIdpInformation(), got.GetIdpInformation()) + }) + } +} diff --git a/internal/api/grpc/user/v2/user_test.go b/internal/api/grpc/user/v2/user_test.go index d697e9ae4f..044099a89a 100644 --- a/internal/api/grpc/user/v2/user_test.go +++ b/internal/api/grpc/user/v2/user_test.go @@ -3,11 +3,21 @@ package user import ( "errors" "testing" + "time" + "github.com/golang/mock/gomock" + "github.com/muhlemmer/gu" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "google.golang.org/protobuf/types/known/timestamppb" + "github.com/zitadel/zitadel/internal/api/grpc" + "github.com/zitadel/zitadel/internal/command" + "github.com/zitadel/zitadel/internal/crypto" + "github.com/zitadel/zitadel/internal/domain" caos_errs "github.com/zitadel/zitadel/internal/errors" + "github.com/zitadel/zitadel/internal/eventstore" + object_pb "github.com/zitadel/zitadel/pkg/grpc/object/v2alpha" user "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha" ) @@ -78,3 +88,118 @@ func Test_hashedPasswordToCommand(t *testing.T) { }) } } + +func Test_intentToIDPInformationPb(t *testing.T) { + decryption := func(err error) crypto.EncryptionAlgorithm { + mCrypto := crypto.NewMockEncryptionAlgorithm(gomock.NewController(t)) + mCrypto.EXPECT().Algorithm().Return("enc") + mCrypto.EXPECT().DecryptionKeyIDs().Return([]string{"id"}) + mCrypto.EXPECT().DecryptString(gomock.Any(), gomock.Any()).DoAndReturn( + func(code []byte, keyID string) (string, error) { + if err != nil { + return "", err + } + return string(code), nil + }) + return mCrypto + } + + type args struct { + intent *command.IDPIntentWriteModel + alg crypto.EncryptionAlgorithm + } + type res struct { + resp *user.RetrieveIdentityProviderInformationResponse + err error + } + tests := []struct { + name string + args args + res res + }{ + { + "decryption invalid key id error", + args{ + intent: &command.IDPIntentWriteModel{ + WriteModel: eventstore.WriteModel{ + AggregateID: "intentID", + ProcessedSequence: 123, + ResourceOwner: "ro", + InstanceID: "instanceID", + ChangeDate: time.Date(2019, 4, 1, 1, 1, 1, 1, time.Local), + }, + IDPID: "idpID", + IDPUser: []byte(`{"id": "id"}`), + IDPAccessToken: &crypto.CryptoValue{ + CryptoType: crypto.TypeEncryption, + Algorithm: "enc", + KeyID: "id", + Crypted: []byte("accessToken"), + }, + IDPIDToken: "idToken", + UserID: "userID", + State: domain.IDPIntentStateSucceeded, + }, + alg: decryption(caos_errs.ThrowInternal(nil, "id", "invalid key id")), + }, + res{ + resp: nil, + err: caos_errs.ThrowInternal(nil, "id", "invalid key id"), + }, + }, + { + "successful", + args{ + intent: &command.IDPIntentWriteModel{ + WriteModel: eventstore.WriteModel{ + AggregateID: "intentID", + ProcessedSequence: 123, + ResourceOwner: "ro", + InstanceID: "instanceID", + ChangeDate: time.Date(2019, 4, 1, 1, 1, 1, 1, time.Local), + }, + IDPID: "idpID", + IDPUser: []byte(`{"id": "id"}`), + IDPAccessToken: &crypto.CryptoValue{ + CryptoType: crypto.TypeEncryption, + Algorithm: "enc", + KeyID: "id", + Crypted: []byte("accessToken"), + }, + IDPIDToken: "idToken", + UserID: "userID", + State: domain.IDPIntentStateSucceeded, + }, + alg: decryption(nil), + }, + res{ + resp: &user.RetrieveIdentityProviderInformationResponse{ + Details: &object_pb.Details{ + Sequence: 123, + ChangeDate: timestamppb.New(time.Date(2019, 4, 1, 1, 1, 1, 1, time.Local)), + ResourceOwner: "ro", + }, + IdpInformation: &user.IDPInformation{ + Access: &user.IDPInformation_Oauth{ + Oauth: &user.IDPOAuthAccessInformation{ + AccessToken: "accessToken", + IdToken: gu.Ptr("idToken"), + }}, + IdpInformation: []byte(`{"id": "id"}`), + }, + }, + err: nil, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := intentToIDPInformationPb(tt.args.intent, tt.args.alg) + require.ErrorIs(t, err, tt.res.err) + assert.Equal(t, tt.res.resp, got) + if tt.res.resp != nil { + grpc.AllFieldsSet(t, got.ProtoReflect()) + } + }) + } +} diff --git a/internal/api/http/cookie.go b/internal/api/http/cookie.go index c7867646cc..ecc243e8ec 100644 --- a/internal/api/http/cookie.go +++ b/internal/api/http/cookie.go @@ -123,8 +123,8 @@ func (c *CookieHandler) SetEncryptedCookie(w http.ResponseWriter, name, domain s return nil } -func (c *CookieHandler) DeleteCookie(w http.ResponseWriter, r *http.Request, name string) { - c.httpSet(w, name, r.Host, "", -1) +func (c *CookieHandler) DeleteCookie(w http.ResponseWriter, name string) { + c.httpSet(w, name, "", "", -1) } func (c *CookieHandler) httpSet(w http.ResponseWriter, name, domain, value string, maxage int) { diff --git a/internal/api/http/middleware/access_interceptor.go b/internal/api/http/middleware/access_interceptor.go index cf52a597d6..7d05619ecc 100644 --- a/internal/api/http/middleware/access_interceptor.go +++ b/internal/api/http/middleware/access_interceptor.go @@ -1,6 +1,7 @@ package middleware import ( + "context" "net" "net/http" "net/url" @@ -32,15 +33,54 @@ type AccessConfig struct { // NewAccessInterceptor intercepts all requests and stores them to the logstore. // If storeOnly is false, it also checks if requests are exhausted. // If requests are exhausted, it also returns http.StatusTooManyRequests and sets a cookie -func NewAccessInterceptor(svc *logstore.Service, cookieHandler *http_utils.CookieHandler, cookieConfig *AccessConfig, storeOnly bool) *AccessInterceptor { +func NewAccessInterceptor(svc *logstore.Service, cookieHandler *http_utils.CookieHandler, cookieConfig *AccessConfig) *AccessInterceptor { return &AccessInterceptor{ svc: svc, cookieHandler: cookieHandler, limitConfig: cookieConfig, - storeOnly: storeOnly, } } +func (a *AccessInterceptor) WithoutLimiting() *AccessInterceptor { + return &AccessInterceptor{ + svc: a.svc, + cookieHandler: a.cookieHandler, + limitConfig: a.limitConfig, + storeOnly: true, + } +} + +func (a *AccessInterceptor) AccessService() *logstore.Service { + return a.svc +} + +func (a *AccessInterceptor) Limit(ctx context.Context) bool { + if !a.svc.Enabled() || a.storeOnly { + return false + } + instance := authz.GetInstance(ctx) + remaining := a.svc.Limit(ctx, instance.InstanceID()) + return remaining != nil && *remaining <= 0 +} + +func (a *AccessInterceptor) SetExhaustedCookie(writer http.ResponseWriter, request *http.Request) { + cookieValue := "true" + host := request.Header.Get(middleware.HTTP1Host) + domain := host + if strings.ContainsAny(host, ":") { + var err error + domain, _, err = net.SplitHostPort(host) + if err != nil { + logging.WithError(err).WithField("host", host).Warning("failed to extract cookie domain from request host") + } + } + a.cookieHandler.SetCookie(writer, a.limitConfig.ExhaustedCookieKey, domain, cookieValue) +} + +func (a *AccessInterceptor) DeleteExhaustedCookie(writer http.ResponseWriter) { + a.cookieHandler.DeleteCookie(writer, a.limitConfig.ExhaustedCookieKey) +} + func (a *AccessInterceptor) Handle(next http.Handler) http.Handler { if !a.svc.Enabled() { return next @@ -49,23 +89,16 @@ func (a *AccessInterceptor) Handle(next http.Handler) http.Handler { ctx := request.Context() tracingCtx, checkSpan := tracing.NewNamedSpan(ctx, "checkAccess") wrappedWriter := &statusRecorder{ResponseWriter: writer, status: 0} - instance := authz.GetInstance(ctx) - limit := false - if !a.storeOnly { - remaining := a.svc.Limit(tracingCtx, instance.InstanceID()) - limit = remaining != nil && *remaining == 0 - } + limited := a.Limit(tracingCtx) checkSpan.End() - if limit { - // Limit can only be true when storeOnly is false, so set the cookie and the response code - SetExhaustedCookie(a.cookieHandler, wrappedWriter, a.limitConfig, request) + if limited { + a.SetExhaustedCookie(wrappedWriter, request) http.Error(wrappedWriter, "quota for authenticated requests is exhausted", http.StatusTooManyRequests) - } else { - if !a.storeOnly { - // If not limited and not storeOnly, ensure the cookie is deleted - DeleteExhaustedCookie(a.cookieHandler, wrappedWriter, request, a.limitConfig) - } - // Always serve if not limited + } + if !limited && !a.storeOnly { + a.DeleteExhaustedCookie(wrappedWriter) + } + if !limited { next.ServeHTTP(wrappedWriter, request) } tracingCtx, writeSpan := tracing.NewNamedSpan(tracingCtx, "writeAccess") @@ -75,6 +108,7 @@ func (a *AccessInterceptor) Handle(next http.Handler) http.Handler { if err != nil { logging.WithError(err).WithField("url", requestURL).Warning("failed to unescape request url") } + instance := authz.GetInstance(tracingCtx) a.svc.Handle(tracingCtx, &access.Record{ LogDate: time.Now(), Protocol: access.HTTP, @@ -90,24 +124,6 @@ func (a *AccessInterceptor) Handle(next http.Handler) http.Handler { }) } -func SetExhaustedCookie(cookieHandler *http_utils.CookieHandler, writer http.ResponseWriter, cookieConfig *AccessConfig, request *http.Request) { - cookieValue := "true" - host := request.Header.Get(middleware.HTTP1Host) - domain := host - if strings.ContainsAny(host, ":") { - var err error - domain, _, err = net.SplitHostPort(host) - if err != nil { - logging.WithError(err).WithField("host", host).Warning("failed to extract cookie domain from request host") - } - } - cookieHandler.SetCookie(writer, cookieConfig.ExhaustedCookieKey, domain, cookieValue) -} - -func DeleteExhaustedCookie(cookieHandler *http_utils.CookieHandler, writer http.ResponseWriter, request *http.Request, cookieConfig *AccessConfig) { - cookieHandler.DeleteCookie(writer, request, cookieConfig.ExhaustedCookieKey) -} - type statusRecorder struct { http.ResponseWriter status int diff --git a/internal/api/idp/idp.go b/internal/api/idp/idp.go new file mode 100644 index 0000000000..37a84f5265 --- /dev/null +++ b/internal/api/idp/idp.go @@ -0,0 +1,246 @@ +package idp + +import ( + "context" + "errors" + "net/http" + + "github.com/gorilla/mux" + "github.com/zitadel/logging" + + "github.com/zitadel/zitadel/internal/api/authz" + http_utils "github.com/zitadel/zitadel/internal/api/http" + "github.com/zitadel/zitadel/internal/command" + "github.com/zitadel/zitadel/internal/crypto" + "github.com/zitadel/zitadel/internal/domain" + z_errs "github.com/zitadel/zitadel/internal/errors" + "github.com/zitadel/zitadel/internal/form" + "github.com/zitadel/zitadel/internal/idp" + "github.com/zitadel/zitadel/internal/idp/providers/azuread" + "github.com/zitadel/zitadel/internal/idp/providers/github" + "github.com/zitadel/zitadel/internal/idp/providers/gitlab" + "github.com/zitadel/zitadel/internal/idp/providers/google" + "github.com/zitadel/zitadel/internal/idp/providers/jwt" + "github.com/zitadel/zitadel/internal/idp/providers/ldap" + "github.com/zitadel/zitadel/internal/idp/providers/oauth" + openid "github.com/zitadel/zitadel/internal/idp/providers/oidc" + "github.com/zitadel/zitadel/internal/query" +) + +const ( + HandlerPrefix = "/idps" + callbackPath = "/callback" + + paramIntentID = "id" + paramToken = "token" + paramUserID = "user" + paramError = "error" + paramErrorDescription = "error_description" +) + +type Handler struct { + commands *command.Commands + queries *query.Queries + parser *form.Parser + encryptionAlgorithm crypto.EncryptionAlgorithm + callbackURL func(ctx context.Context) string +} + +type externalIDPCallbackData struct { + State string `schema:"state"` + Code string `schema:"code"` + Error string `schema:"error"` + ErrorDescription string `schema:"error_description"` +} + +// CallbackURL generates the instance specific URL to the IDP callback handler +func CallbackURL(externalSecure bool) func(ctx context.Context) string { + return func(ctx context.Context) string { + return http_utils.BuildOrigin(authz.GetInstance(ctx).RequestedHost(), externalSecure) + HandlerPrefix + callbackPath + } +} + +func NewHandler( + commands *command.Commands, + queries *query.Queries, + encryptionAlgorithm crypto.EncryptionAlgorithm, + externalSecure bool, + instanceInterceptor func(next http.Handler) http.Handler, +) http.Handler { + h := &Handler{ + commands: commands, + queries: queries, + parser: form.NewParser(), + encryptionAlgorithm: encryptionAlgorithm, + callbackURL: CallbackURL(externalSecure), + } + + router := mux.NewRouter() + router.Use(instanceInterceptor) + router.HandleFunc(callbackPath, h.handleCallback) + return router +} + +func (h *Handler) handleCallback(w http.ResponseWriter, r *http.Request) { + data, err := h.parseCallbackRequest(r) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + intent := h.getActiveIntent(w, r, data.State) + if intent == nil { + // if we didn't get an active intent the error was already handled (either redirected or display directly) + return + } + + ctx := r.Context() + // the provider might have returned an error + if data.Error != "" { + cmdErr := h.commands.FailIDPIntent(ctx, intent, reason(data.Error, data.ErrorDescription)) + logging.WithFields("intent", intent.AggregateID).OnError(cmdErr).Error("failed to push failed event on idp intent") + redirectToFailureURL(w, r, intent, data.Error, data.ErrorDescription) + return + } + + provider, err := h.commands.GetProvider(ctx, intent.IDPID, h.callbackURL(ctx)) + if err != nil { + cmdErr := h.commands.FailIDPIntent(ctx, intent, err.Error()) + logging.WithFields("intent", intent.AggregateID).OnError(cmdErr).Error("failed to push failed event on idp intent") + redirectToFailureURLErr(w, r, intent, err) + return + } + + idpUser, idpSession, err := h.fetchIDPUser(ctx, provider, data.Code) + if err != nil { + cmdErr := h.commands.FailIDPIntent(ctx, intent, err.Error()) + logging.WithFields("intent", intent.AggregateID).OnError(cmdErr).Error("failed to push failed event on idp intent") + redirectToFailureURLErr(w, r, intent, err) + return + } + userID, err := h.checkExternalUser(ctx, intent.IDPID, idpUser.GetID()) + logging.WithFields("intent", intent.AggregateID).OnError(err).Error("could not check if idp user already exists") + + token, err := h.commands.SucceedIDPIntent(ctx, intent, idpUser, idpSession, userID) + if err != nil { + redirectToFailureURLErr(w, r, intent, z_errs.ThrowInternal(err, "IDP-JdD3g", "Errors.Intent.TokenCreationFailed")) + return + } + redirectToSuccessURL(w, r, intent, token, userID) +} + +func (h *Handler) parseCallbackRequest(r *http.Request) (*externalIDPCallbackData, error) { + data := new(externalIDPCallbackData) + err := h.parser.Parse(r, data) + if err != nil { + return nil, err + } + if data.State == "" { + return nil, z_errs.ThrowInvalidArgument(nil, "IDP-Hk38e", "Errors.Intent.StateMissing") + } + return data, nil +} + +func (h *Handler) getActiveIntent(w http.ResponseWriter, r *http.Request, state string) *command.IDPIntentWriteModel { + intent, err := h.commands.GetIntentWriteModel(r.Context(), state, "") + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return nil + } + if intent.State == domain.IDPIntentStateUnspecified { + http.Error(w, reason("IDP-Hk38e", "Errors.Intent.NotStarted"), http.StatusBadRequest) + return nil + } + if intent.State != domain.IDPIntentStateStarted { + redirectToFailureURL(w, r, intent, "IDP-Sfrgs", "Errors.Intent.NotStarted") + return nil + } + return intent +} + +func redirectToSuccessURL(w http.ResponseWriter, r *http.Request, intent *command.IDPIntentWriteModel, token, userID string) { + queries := intent.SuccessURL.Query() + queries.Set(paramIntentID, intent.AggregateID) + queries.Set(paramToken, token) + if userID != "" { + queries.Set(paramUserID, userID) + } + intent.SuccessURL.RawQuery = queries.Encode() + http.Redirect(w, r, intent.SuccessURL.String(), http.StatusFound) +} + +func redirectToFailureURLErr(w http.ResponseWriter, r *http.Request, i *command.IDPIntentWriteModel, err error) { + msg := err.Error() + var description string + zErr := new(z_errs.CaosError) + if errors.As(err, &zErr) { + msg = zErr.GetID() + description = zErr.GetMessage() // TODO: i18n? + } + redirectToFailureURL(w, r, i, msg, description) +} + +func redirectToFailureURL(w http.ResponseWriter, r *http.Request, i *command.IDPIntentWriteModel, err, description string) { + queries := i.FailureURL.Query() + queries.Set(paramIntentID, i.AggregateID) + queries.Set(paramError, err) + queries.Set(paramErrorDescription, description) + i.FailureURL.RawQuery = queries.Encode() + http.Redirect(w, r, i.FailureURL.String(), http.StatusFound) +} + +func (h *Handler) fetchIDPUser(ctx context.Context, identityProvider idp.Provider, code string) (user idp.User, idpTokens idp.Session, err error) { + var session idp.Session + switch provider := identityProvider.(type) { + case *oauth.Provider: + session = &oauth.Session{Provider: provider, Code: code} + case *openid.Provider: + session = &openid.Session{Provider: provider, Code: code} + case *azuread.Provider: + session = &oauth.Session{Provider: provider.Provider, Code: code} + case *github.Provider: + session = &oauth.Session{Provider: provider.Provider, Code: code} + case *gitlab.Provider: + session = &openid.Session{Provider: provider.Provider, Code: code} + case *google.Provider: + session = &openid.Session{Provider: provider.Provider, Code: code} + case *jwt.Provider, *ldap.Provider: + return nil, nil, z_errs.ThrowInvalidArgument(nil, "IDP-52jmn", "Errors.ExternalIDP.IDPTypeNotImplemented") + default: + return nil, nil, z_errs.ThrowUnimplemented(nil, "IDP-SSDg", "Errors.ExternalIDP.IDPTypeNotImplemented") + } + + user, err = session.FetchUser(ctx) + if err != nil { + return nil, nil, err + } + return user, session, nil +} + +func (h *Handler) checkExternalUser(ctx context.Context, idpID, externalUserID string) (userID string, err error) { + idQuery, err := query.NewIDPUserLinkIDPIDSearchQuery(idpID) + if err != nil { + return "", err + } + externalIDQuery, err := query.NewIDPUserLinksExternalIDSearchQuery(externalUserID) + if err != nil { + return "", err + } + queries := []query.SearchQuery{ + idQuery, externalIDQuery, + } + links, err := h.queries.IDPUserLinks(ctx, &query.IDPUserLinksSearchQuery{Queries: queries}, false) + if err != nil { + return "", err + } + if len(links.Links) != 1 { + return "", nil + } + return links.Links[0].UserID, nil +} + +func reason(err, description string) string { + if description == "" { + return err + } + return err + ": " + description +} diff --git a/internal/api/idp/idp_test.go b/internal/api/idp/idp_test.go new file mode 100644 index 0000000000..1e6395197e --- /dev/null +++ b/internal/api/idp/idp_test.go @@ -0,0 +1,220 @@ +package idp + +import ( + "net/http/httptest" + "net/url" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/zitadel/zitadel/internal/command" + z_errors "github.com/zitadel/zitadel/internal/errors" + "github.com/zitadel/zitadel/internal/form" +) + +func Test_redirectToSuccessURL(t *testing.T) { + type args struct { + id string + userID string + token string + failureURL string + successURL string + } + type res struct { + want string + } + tests := []struct { + name string + args args + res res + }{ + { + "redirect", + args{ + id: "id", + token: "token", + failureURL: "https://example.com/failure", + successURL: "https://example.com/success", + }, + res{ + "https://example.com/success?id=id&token=token", + }, + }, + { + "redirect with userID", + args{ + id: "id", + userID: "user", + token: "token", + failureURL: "https://example.com/failure", + successURL: "https://example.com/success", + }, + res{ + "https://example.com/success?id=id&token=token&user=user", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + req := httptest.NewRequest("GET", "http://example.com", nil) + resp := httptest.NewRecorder() + + wm := command.NewIDPIntentWriteModel(tt.args.id, tt.args.id) + wm.FailureURL, _ = url.Parse(tt.args.failureURL) + wm.SuccessURL, _ = url.Parse(tt.args.successURL) + + redirectToSuccessURL(resp, req, wm, tt.args.token, tt.args.userID) + assert.Equal(t, tt.res.want, resp.Header().Get("Location")) + }) + } +} + +func Test_redirectToFailureURL(t *testing.T) { + type args struct { + id string + failureURL string + successURL string + err string + desc string + } + type res struct { + want string + } + tests := []struct { + name string + args args + res res + }{ + { + "redirect", + args{ + id: "id", + failureURL: "https://example.com/failure", + successURL: "https://example.com/success", + }, + res{ + "https://example.com/failure?error=&error_description=&id=id", + }, + }, + { + "redirect with error", + args{ + id: "id", + failureURL: "https://example.com/failure", + successURL: "https://example.com/success", + err: "test", + desc: "testdesc", + }, + res{ + "https://example.com/failure?error=test&error_description=testdesc&id=id", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + req := httptest.NewRequest("GET", "http://example.com", nil) + resp := httptest.NewRecorder() + + wm := command.NewIDPIntentWriteModel(tt.args.id, tt.args.id) + wm.FailureURL, _ = url.Parse(tt.args.failureURL) + wm.SuccessURL, _ = url.Parse(tt.args.successURL) + + redirectToFailureURL(resp, req, wm, tt.args.err, tt.args.desc) + assert.Equal(t, tt.res.want, resp.Header().Get("Location")) + }) + } +} + +func Test_redirectToFailureURLErr(t *testing.T) { + type args struct { + id string + failureURL string + successURL string + err error + } + type res struct { + want string + } + tests := []struct { + name string + args args + res res + }{ + { + "redirect with error", + args{ + id: "id", + failureURL: "https://example.com/failure", + successURL: "https://example.com/success", + err: z_errors.ThrowError(nil, "test", "testdesc"), + }, + res{ + "https://example.com/failure?error=test&error_description=testdesc&id=id", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + req := httptest.NewRequest("GET", "http://example.com", nil) + resp := httptest.NewRecorder() + + wm := command.NewIDPIntentWriteModel(tt.args.id, tt.args.id) + wm.FailureURL, _ = url.Parse(tt.args.failureURL) + wm.SuccessURL, _ = url.Parse(tt.args.successURL) + + redirectToFailureURLErr(resp, req, wm, tt.args.err) + assert.Equal(t, tt.res.want, resp.Header().Get("Location")) + }) + } +} + +func Test_parseCallbackRequest(t *testing.T) { + type args struct { + url string + } + type res struct { + want *externalIDPCallbackData + err bool + } + tests := []struct { + name string + args args + res res + }{ + { + "no state", + args{ + url: "https://example.com?state=&code=code&error=error&error_description=desc", + }, + res{ + err: true, + }, + }, + { + "parse", + args{ + url: "https://example.com?state=state&code=code&error=error&error_description=desc", + }, + res{ + want: &externalIDPCallbackData{ + State: "state", + Code: "code", + Error: "error", + ErrorDescription: "desc", + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + req := httptest.NewRequest("GET", tt.args.url, nil) + handler := Handler{parser: form.NewParser()} + + data, err := handler.parseCallbackRequest(req) + if tt.res.err { + assert.Error(t, err) + } + assert.Equal(t, tt.res.want, data) + }) + } +} diff --git a/internal/api/ui/console/console.go b/internal/api/ui/console/console.go index 45503ca0c1..320d753b4d 100644 --- a/internal/api/ui/console/console.go +++ b/internal/api/ui/console/console.go @@ -91,7 +91,7 @@ func (f *file) Stat() (_ fs.FileInfo, err error) { return f, nil } -func Start(config Config, externalSecure bool, issuer op.IssuerFromRequest, callDurationInterceptor, instanceHandler, accessInterceptor func(http.Handler) http.Handler, customerPortal string) (http.Handler, error) { +func Start(config Config, externalSecure bool, issuer op.IssuerFromRequest, callDurationInterceptor, instanceHandler func(http.Handler) http.Handler, limitingAccessInterceptor *middleware.AccessInterceptor, customerPortal string) (http.Handler, error) { fSys, err := fs.Sub(static, "static") if err != nil { return nil, err @@ -106,20 +106,27 @@ func Start(config Config, externalSecure bool, issuer op.IssuerFromRequest, call handler := mux.NewRouter() - handler.Use(callDurationInterceptor, instanceHandler, security, accessInterceptor) + handler.Use(callDurationInterceptor, instanceHandler, security, limitingAccessInterceptor.WithoutLimiting().Handle) handler.Handle(envRequestPath, middleware.TelemetryHandler()(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { url := http_util.BuildOrigin(r.Host, externalSecure) - instance := authz.GetInstance(r.Context()) + ctx := r.Context() + instance := authz.GetInstance(ctx) instanceMgmtURL, err := templateInstanceManagementURL(config.InstanceManagementURL, instance) if err != nil { http.Error(w, fmt.Sprintf("unable to template instance management url for console: %v", err), http.StatusInternalServerError) return } - environmentJSON, err := createEnvironmentJSON(url, issuer(r), instance.ConsoleClientID(), customerPortal, instanceMgmtURL) + exhausted := limitingAccessInterceptor.Limit(ctx) + environmentJSON, err := createEnvironmentJSON(url, issuer(r), instance.ConsoleClientID(), customerPortal, instanceMgmtURL, exhausted) if err != nil { http.Error(w, fmt.Sprintf("unable to marshal env for console: %v", err), http.StatusInternalServerError) return } + if exhausted { + limitingAccessInterceptor.SetExhaustedCookie(w, r) + } else { + limitingAccessInterceptor.DeleteExhaustedCookie(w) + } _, err = w.Write(environmentJSON) logging.OnError(err).Error("error serving environment.json") }))) @@ -148,19 +155,21 @@ func csp() *middleware.CSP { return &csp } -func createEnvironmentJSON(api, issuer, clientID, customerPortal, instanceMgmtUrl string) ([]byte, error) { +func createEnvironmentJSON(api, issuer, clientID, customerPortal, instanceMgmtUrl string, exhausted bool) ([]byte, error) { environment := struct { API string `json:"api,omitempty"` Issuer string `json:"issuer,omitempty"` ClientID string `json:"clientid,omitempty"` CustomerPortal string `json:"customer_portal,omitempty"` InstanceManagementURL string `json:"instance_management_url,omitempty"` + Exhausted bool `json:"exhausted,omitempty"` }{ API: api, Issuer: issuer, ClientID: clientID, CustomerPortal: customerPortal, InstanceManagementURL: instanceMgmtUrl, + Exhausted: exhausted, } return json.Marshal(environment) } diff --git a/internal/command/command.go b/internal/command/command.go index e9fa9f739f..3c804576be 100644 --- a/internal/command/command.go +++ b/internal/command/command.go @@ -15,6 +15,7 @@ import ( "github.com/zitadel/zitadel/internal/eventstore" "github.com/zitadel/zitadel/internal/id" "github.com/zitadel/zitadel/internal/repository/action" + "github.com/zitadel/zitadel/internal/repository/idpintent" instance_repo "github.com/zitadel/zitadel/internal/repository/instance" "github.com/zitadel/zitadel/internal/repository/keypair" "github.com/zitadel/zitadel/internal/repository/org" @@ -31,7 +32,7 @@ type Commands struct { httpClient *http.Client checkPermission domain.PermissionCheck - newEmailCode func(ctx context.Context, filter preparation.FilterToQueryReducer, codeAlg crypto.EncryptionAlgorithm) (*CryptoCodeWithExpiry, error) + newCode cryptoCodeFunc eventstore *eventstore.Eventstore static static.Storage @@ -108,7 +109,7 @@ func StartCommands( webauthnConfig: webAuthN, httpClient: httpClient, checkPermission: permissionCheck, - newEmailCode: newEmailCode, + newCode: newCryptoCodeWithExpiry, sessionTokenCreator: sessionTokenCreator(idGenerator, sessionAlg), sessionTokenVerifier: sessionTokenVerifier, } @@ -122,6 +123,7 @@ func StartCommands( action.RegisterEventMappers(repo.eventstore) quota.RegisterEventMappers(repo.eventstore) session.RegisterEventMappers(repo.eventstore) + idpintent.RegisterEventMappers(repo.eventstore) repo.userPasswordAlg = crypto.NewBCrypt(defaults.SecretGenerators.PasswordSaltCost) repo.machineKeySize = int(defaults.SecretGenerators.MachineKeySize) @@ -139,11 +141,21 @@ func StartCommands( return repo, nil } -func AppendAndReduce(object interface { +type AppendReducer interface { AppendEvents(...eventstore.Event) // TODO: Why is it allowed to return an error here? Reduce() error -}, events ...eventstore.Event) error { +} + +func (c *Commands) pushAppendAndReduce(ctx context.Context, object AppendReducer, cmds ...eventstore.Command) error { + events, err := c.eventstore.Push(ctx, cmds...) + if err != nil { + return err + } + return AppendAndReduce(object, events...) +} + +func AppendAndReduce(object AppendReducer, events ...eventstore.Event) error { object.AppendEvents(events...) return object.Reduce() } diff --git a/internal/command/crypto.go b/internal/command/crypto.go index 404b2221f9..e94f664633 100644 --- a/internal/command/crypto.go +++ b/internal/command/crypto.go @@ -10,6 +10,8 @@ import ( "github.com/zitadel/zitadel/internal/errors" ) +type cryptoCodeFunc func(ctx context.Context, filter preparation.FilterToQueryReducer, typ domain.SecretGeneratorType, alg crypto.Crypto) (*CryptoCodeWithExpiry, error) + type CryptoCodeWithExpiry struct { Crypted *crypto.CryptoValue Plain string @@ -17,42 +19,50 @@ type CryptoCodeWithExpiry struct { } func newCryptoCodeWithExpiry(ctx context.Context, filter preparation.FilterToQueryReducer, typ domain.SecretGeneratorType, alg crypto.Crypto) (*CryptoCodeWithExpiry, error) { - config, err := secretGeneratorConfig(ctx, filter, typ) + gen, config, err := secretGenerator(ctx, filter, typ, alg) if err != nil { return nil, err } - - code := new(CryptoCodeWithExpiry) - switch a := alg.(type) { - case crypto.HashAlgorithm: - code.Crypted, code.Plain, err = crypto.NewCode(crypto.NewHashGenerator(*config, a)) - case crypto.EncryptionAlgorithm: - code.Crypted, code.Plain, err = crypto.NewCode(crypto.NewEncryptionGenerator(*config, a)) - default: - return nil, errors.ThrowInternal(nil, "COMMA-RreV6", "Errors.Internal") - } + crypted, plain, err := crypto.NewCode(gen) if err != nil { return nil, err } + return &CryptoCodeWithExpiry{ + Crypted: crypted, + Plain: plain, + Expiry: config.Expiry, + }, nil +} - code.Expiry = config.Expiry - return code, nil +func verifyCryptoCode(ctx context.Context, filter preparation.FilterToQueryReducer, typ domain.SecretGeneratorType, alg crypto.Crypto, creation time.Time, expiry time.Duration, crypted *crypto.CryptoValue, plain string) error { + gen, _, err := secretGenerator(ctx, filter, typ, alg) + if err != nil { + return err + } + return crypto.VerifyCode(creation, expiry, crypted, plain, gen) } func newCryptoCodeWithPlain(ctx context.Context, filter preparation.FilterToQueryReducer, typ domain.SecretGeneratorType, alg crypto.Crypto) (value *crypto.CryptoValue, plain string, err error) { - config, err := secretGeneratorConfig(ctx, filter, typ) + gen, _, err := secretGenerator(ctx, filter, typ, alg) if err != nil { return nil, "", err } + return crypto.NewCode(gen) +} +func secretGenerator(ctx context.Context, filter preparation.FilterToQueryReducer, typ domain.SecretGeneratorType, alg crypto.Crypto) (crypto.Generator, *crypto.GeneratorConfig, error) { + config, err := secretGeneratorConfig(ctx, filter, typ) + if err != nil { + return nil, nil, err + } switch a := alg.(type) { case crypto.HashAlgorithm: - return crypto.NewCode(crypto.NewHashGenerator(*config, a)) + return crypto.NewHashGenerator(*config, a), config, nil case crypto.EncryptionAlgorithm: - return crypto.NewCode(crypto.NewEncryptionGenerator(*config, a)) + return crypto.NewEncryptionGenerator(*config, a), config, nil + default: + return nil, nil, errors.ThrowInternalf(nil, "COMMA-RreV6", "Errors.Internal unsupported crypto algorithm type %T", a) } - - return nil, "", errors.ThrowInvalidArgument(nil, "V2-NGESt", "Errors.Internal") } func secretGeneratorConfig(ctx context.Context, filter preparation.FilterToQueryReducer, typ domain.SecretGeneratorType) (*crypto.GeneratorConfig, error) { diff --git a/internal/command/crypto_test.go b/internal/command/crypto_test.go new file mode 100644 index 0000000000..a846ae43a5 --- /dev/null +++ b/internal/command/crypto_test.go @@ -0,0 +1,242 @@ +package command + +import ( + "context" + "io" + "testing" + "time" + + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/zitadel/zitadel/internal/command/preparation" + "github.com/zitadel/zitadel/internal/crypto" + "github.com/zitadel/zitadel/internal/domain" + "github.com/zitadel/zitadel/internal/errors" + "github.com/zitadel/zitadel/internal/eventstore" + "github.com/zitadel/zitadel/internal/repository/instance" +) + +func mockCode(code string, exp time.Duration) cryptoCodeFunc { + return func(ctx context.Context, filter preparation.FilterToQueryReducer, _ domain.SecretGeneratorType, alg crypto.Crypto) (*CryptoCodeWithExpiry, error) { + return &CryptoCodeWithExpiry{ + Crypted: &crypto.CryptoValue{ + CryptoType: crypto.TypeEncryption, + Algorithm: "enc", + KeyID: "id", + Crypted: []byte(code), + }, + Plain: code, + Expiry: exp, + }, nil + } +} + +var ( + testGeneratorConfig = crypto.GeneratorConfig{ + Length: 12, + Expiry: 60000000000, + IncludeLowerLetters: true, + IncludeUpperLetters: true, + IncludeDigits: true, + IncludeSymbols: true, + } +) + +func testSecretGeneratorAddedEvent(typ domain.SecretGeneratorType) *instance.SecretGeneratorAddedEvent { + return instance.NewSecretGeneratorAddedEvent(context.Background(), + &instance.NewAggregate("inst1").Aggregate, typ, + testGeneratorConfig.Length, + testGeneratorConfig.Expiry, + testGeneratorConfig.IncludeLowerLetters, + testGeneratorConfig.IncludeUpperLetters, + testGeneratorConfig.IncludeDigits, + testGeneratorConfig.IncludeSymbols, + ) +} + +func Test_newCryptoCode(t *testing.T) { + type args struct { + typ domain.SecretGeneratorType + alg crypto.Crypto + } + tests := []struct { + name string + eventstore *eventstore.Eventstore + args args + wantErr error + }{ + { + name: "filter config error", + eventstore: eventstoreExpect(t, expectFilterError(io.ErrClosedPipe)), + args: args{ + typ: domain.SecretGeneratorTypeVerifyEmailCode, + alg: crypto.CreateMockHashAlg(gomock.NewController(t)), + }, + wantErr: io.ErrClosedPipe, + }, + { + name: "success", + eventstore: eventstoreExpect(t, expectFilter( + eventFromEventPusher(testSecretGeneratorAddedEvent(domain.SecretGeneratorTypeVerifyEmailCode)), + )), + args: args{ + typ: domain.SecretGeneratorTypeVerifyEmailCode, + alg: crypto.CreateMockHashAlg(gomock.NewController(t)), + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := newCryptoCodeWithExpiry(context.Background(), tt.eventstore.Filter, tt.args.typ, tt.args.alg) + require.ErrorIs(t, err, tt.wantErr) + if tt.wantErr == nil { + require.NotNil(t, got) + assert.NotNil(t, got.Crypted) + assert.NotEmpty(t, got) + assert.Equal(t, testGeneratorConfig.Expiry, got.Expiry) + } + }) + } +} + +func Test_verifyCryptoCode(t *testing.T) { + es := eventstoreExpect(t, expectFilter( + eventFromEventPusher(testSecretGeneratorAddedEvent(domain.SecretGeneratorTypeVerifyEmailCode)), + )) + code, err := newCryptoCodeWithExpiry(context.Background(), es.Filter, domain.SecretGeneratorTypeVerifyEmailCode, crypto.CreateMockHashAlg(gomock.NewController(t))) + require.NoError(t, err) + + type args struct { + typ domain.SecretGeneratorType + alg crypto.Crypto + expiry time.Duration + crypted *crypto.CryptoValue + plain string + } + tests := []struct { + name string + eventsore *eventstore.Eventstore + args args + wantErr bool + }{ + { + name: "filter config error", + eventsore: eventstoreExpect(t, expectFilterError(io.ErrClosedPipe)), + args: args{ + typ: domain.SecretGeneratorTypeVerifyEmailCode, + alg: crypto.CreateMockHashAlg(gomock.NewController(t)), + expiry: code.Expiry, + crypted: code.Crypted, + plain: code.Plain, + }, + wantErr: true, + }, + { + name: "success", + eventsore: eventstoreExpect(t, expectFilter( + eventFromEventPusher(testSecretGeneratorAddedEvent(domain.SecretGeneratorTypeVerifyEmailCode)), + )), + args: args{ + typ: domain.SecretGeneratorTypeVerifyEmailCode, + alg: crypto.CreateMockHashAlg(gomock.NewController(t)), + expiry: code.Expiry, + crypted: code.Crypted, + plain: code.Plain, + }, + }, + { + name: "wrong plain", + eventsore: eventstoreExpect(t, expectFilter( + eventFromEventPusher(testSecretGeneratorAddedEvent(domain.SecretGeneratorTypeVerifyEmailCode)), + )), + args: args{ + typ: domain.SecretGeneratorTypeVerifyEmailCode, + alg: crypto.CreateMockHashAlg(gomock.NewController(t)), + expiry: code.Expiry, + crypted: code.Crypted, + plain: "wrong", + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := verifyCryptoCode(context.Background(), tt.eventsore.Filter, tt.args.typ, tt.args.alg, time.Now(), tt.args.expiry, tt.args.crypted, tt.args.plain) + if tt.wantErr { + assert.Error(t, err) + return + } + require.NoError(t, err) + }) + } +} + +func Test_secretGenerator(t *testing.T) { + type args struct { + typ domain.SecretGeneratorType + alg crypto.Crypto + } + tests := []struct { + name string + eventsore *eventstore.Eventstore + args args + want crypto.Generator + wantConf *crypto.GeneratorConfig + wantErr error + }{ + { + name: "filter config error", + eventsore: eventstoreExpect(t, expectFilterError(io.ErrClosedPipe)), + args: args{ + typ: domain.SecretGeneratorTypeVerifyEmailCode, + alg: crypto.CreateMockHashAlg(gomock.NewController(t)), + }, + wantErr: io.ErrClosedPipe, + }, + { + name: "hash generator", + eventsore: eventstoreExpect(t, expectFilter( + eventFromEventPusher(testSecretGeneratorAddedEvent(domain.SecretGeneratorTypeVerifyEmailCode)), + )), + args: args{ + typ: domain.SecretGeneratorTypeVerifyEmailCode, + alg: crypto.CreateMockHashAlg(gomock.NewController(t)), + }, + want: crypto.NewHashGenerator(testGeneratorConfig, crypto.CreateMockHashAlg(gomock.NewController(t))), + wantConf: &testGeneratorConfig, + }, + { + name: "encryption generator", + eventsore: eventstoreExpect(t, expectFilter( + eventFromEventPusher(testSecretGeneratorAddedEvent(domain.SecretGeneratorTypeVerifyEmailCode)), + )), + args: args{ + typ: domain.SecretGeneratorTypeVerifyEmailCode, + alg: crypto.CreateMockEncryptionAlg(gomock.NewController(t)), + }, + want: crypto.NewEncryptionGenerator(testGeneratorConfig, crypto.CreateMockEncryptionAlg(gomock.NewController(t))), + wantConf: &testGeneratorConfig, + }, + { + name: "unsupported type", + eventsore: eventstoreExpect(t, expectFilter( + eventFromEventPusher(testSecretGeneratorAddedEvent(domain.SecretGeneratorTypeVerifyEmailCode)), + )), + args: args{ + typ: domain.SecretGeneratorTypeVerifyEmailCode, + alg: nil, + }, + wantErr: errors.ThrowInternalf(nil, "COMMA-RreV6", "Errors.Internal unsupported crypto algorithm type %T", nil), + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, gotConf, err := secretGenerator(context.Background(), tt.eventsore.Filter, tt.args.typ, tt.args.alg) + require.ErrorIs(t, err, tt.wantErr) + assert.IsType(t, tt.want, got) + assert.Equal(t, tt.wantConf, gotConf) + }) + } +} diff --git a/internal/command/email.go b/internal/command/email.go index 0bfbcd6af6..f54b3de8e4 100644 --- a/internal/command/email.go +++ b/internal/command/email.go @@ -23,6 +23,6 @@ func (e *Email) Validate() error { return e.Address.Validate() } -func newEmailCode(ctx context.Context, filter preparation.FilterToQueryReducer, alg crypto.EncryptionAlgorithm) (*CryptoCodeWithExpiry, error) { - return newCryptoCodeWithExpiry(ctx, filter, domain.SecretGeneratorTypeVerifyEmailCode, alg) +func (c *Commands) newEmailCode(ctx context.Context, filter preparation.FilterToQueryReducer, alg crypto.EncryptionAlgorithm) (*CryptoCodeWithExpiry, error) { + return c.newCode(ctx, filter, domain.SecretGeneratorTypeVerifyEmailCode, alg) } diff --git a/internal/command/idp.go b/internal/command/idp.go index a5605e8a3a..4e34aa6e42 100644 --- a/internal/command/idp.go +++ b/internal/command/idp.go @@ -6,6 +6,7 @@ import ( "github.com/zitadel/zitadel/internal/api/authz" "github.com/zitadel/zitadel/internal/command/preparation" + "github.com/zitadel/zitadel/internal/errors" "github.com/zitadel/zitadel/internal/repository/idp" ) @@ -139,3 +140,37 @@ func ExistsIDP(ctx context.Context, filter preparation.FilterToQueryReducer, id, } return instanceWriteModel.State.Exists(), nil } + +func IDPProviderWriteModel(ctx context.Context, filter preparation.FilterToQueryReducer, id string) (_ *AllIDPWriteModel, err error) { + writeModel := NewIDPTypeWriteModel(id) + events, err := filter(ctx, writeModel.Query()) + if err != nil { + return nil, err + } + if len(events) == 0 { + return nil, errors.ThrowPreconditionFailed(nil, "COMMAND-as02jin", "Errors.IDPConfig.NotExisting") + } + writeModel.AppendEvents(events...) + if err := writeModel.Reduce(); err != nil { + return nil, err + } + allWriteModel, err := NewAllIDPWriteModel( + writeModel.ResourceOwner, + writeModel.ResourceOwner == writeModel.InstanceID, + writeModel.ID, + writeModel.Type, + ) + if err != nil { + return nil, err + } + events, err = filter(ctx, allWriteModel.Query()) + if err != nil { + return nil, err + } + allWriteModel.AppendEvents(events...) + if err := allWriteModel.Reduce(); err != nil { + return nil, err + } + + return allWriteModel, err +} diff --git a/internal/command/idp_intent.go b/internal/command/idp_intent.go new file mode 100644 index 0000000000..1045b77013 --- /dev/null +++ b/internal/command/idp_intent.go @@ -0,0 +1,177 @@ +package command + +import ( + "context" + "encoding/base64" + "encoding/json" + "net/url" + + "github.com/zitadel/oidc/v2/pkg/oidc" + + "github.com/zitadel/zitadel/internal/command/preparation" + "github.com/zitadel/zitadel/internal/crypto" + "github.com/zitadel/zitadel/internal/domain" + "github.com/zitadel/zitadel/internal/errors" + "github.com/zitadel/zitadel/internal/eventstore" + "github.com/zitadel/zitadel/internal/idp" + "github.com/zitadel/zitadel/internal/idp/providers/jwt" + "github.com/zitadel/zitadel/internal/idp/providers/oauth" + openid "github.com/zitadel/zitadel/internal/idp/providers/oidc" + "github.com/zitadel/zitadel/internal/repository/idpintent" +) + +func (c *Commands) prepareCreateIntent(writeModel *IDPIntentWriteModel, idpID string, successURL, failureURL string) preparation.Validation { + return func() (_ preparation.CreateCommands, err error) { + if idpID == "" { + return nil, errors.ThrowInvalidArgument(nil, "COMMAND-x8j2bk", "Errors.Intent.IDPMissing") + } + successURL, err := url.Parse(successURL) + if err != nil { + return nil, errors.ThrowInvalidArgument(nil, "COMMAND-x8j3bk", "Errors.Intent.SuccessURLMissing") + } + failureURL, err := url.Parse(failureURL) + if err != nil { + return nil, errors.ThrowInvalidArgument(nil, "COMMAND-x8j4bk", "Errors.Intent.FailureURLMissing") + } + return func(ctx context.Context, filter preparation.FilterToQueryReducer) ([]eventstore.Command, error) { + err = getIDPIntentWriteModel(ctx, writeModel, filter) + if err != nil { + return nil, err + } + exists, err := ExistsIDP(ctx, filter, idpID, writeModel.ResourceOwner) + if !exists || err != nil { + return nil, errors.ThrowPreconditionFailed(err, "COMMAND-39n221fs", "Errors.IDPConfig.NotExisting") + } + return []eventstore.Command{ + idpintent.NewStartedEvent(ctx, writeModel.aggregate, successURL, failureURL, idpID), + }, nil + }, nil + } +} + +func (c *Commands) CreateIntent(ctx context.Context, idpID, successURL, failureURL, resourceOwner string) (string, *domain.ObjectDetails, error) { + id, err := c.idGenerator.Next() + if err != nil { + return "", nil, err + } + writeModel := NewIDPIntentWriteModel(id, resourceOwner) + if err != nil { + return "", nil, err + } + + cmds, err := preparation.PrepareCommands(ctx, c.eventstore.Filter, c.prepareCreateIntent(writeModel, idpID, successURL, failureURL)) + if err != nil { + return "", nil, err + } + pushedEvents, err := c.eventstore.Push(ctx, cmds...) + if err != nil { + return "", nil, err + } + err = AppendAndReduce(writeModel, pushedEvents...) + if err != nil { + return "", nil, err + } + return id, writeModelToObjectDetails(&writeModel.WriteModel), nil +} + +func (c *Commands) GetProvider(ctx context.Context, idpID, callbackURL string) (idp.Provider, error) { + writeModel, err := IDPProviderWriteModel(ctx, c.eventstore.Filter, idpID) + if err != nil { + return nil, err + } + return writeModel.ToProvider(callbackURL, c.idpConfigEncryption) +} + +func (c *Commands) AuthURLFromProvider(ctx context.Context, idpID, state, callbackURL string) (string, error) { + provider, err := c.GetProvider(ctx, idpID, callbackURL) + if err != nil { + return "", err + } + session, err := provider.BeginAuth(ctx, state) + if err != nil { + return "", err + } + return session.GetAuthURL(), nil +} + +func getIDPIntentWriteModel(ctx context.Context, writeModel *IDPIntentWriteModel, filter preparation.FilterToQueryReducer) error { + events, err := filter(ctx, writeModel.Query()) + if err != nil { + return err + } + if len(events) == 0 { + return nil + } + writeModel.AppendEvents(events...) + return writeModel.Reduce() +} + +func (c *Commands) SucceedIDPIntent(ctx context.Context, writeModel *IDPIntentWriteModel, idpUser idp.User, idpSession idp.Session, userID string) (string, error) { + token, err := c.idpConfigEncryption.Encrypt([]byte(writeModel.AggregateID)) + if err != nil { + return "", err + } + accessToken, idToken, err := tokensForSucceededIDPIntent(idpSession, c.idpConfigEncryption) + if err != nil { + return "", err + } + idpInfo, err := json.Marshal(idpUser) + if err != nil { + return "", err + } + cmd, err := idpintent.NewSucceededEvent( + ctx, + &idpintent.NewAggregate(writeModel.AggregateID, writeModel.ResourceOwner).Aggregate, + idpInfo, + userID, + accessToken, + idToken, + ) + if err != nil { + return "", err + } + err = c.pushAppendAndReduce(ctx, writeModel, cmd) + if err != nil { + return "", err + } + return base64.RawURLEncoding.EncodeToString(token), nil +} + +func (c *Commands) FailIDPIntent(ctx context.Context, writeModel *IDPIntentWriteModel, reason string) error { + cmd := idpintent.NewFailedEvent( + ctx, + &idpintent.NewAggregate(writeModel.AggregateID, writeModel.ResourceOwner).Aggregate, + reason, + ) + _, err := c.eventstore.Push(ctx, cmd) + return err +} + +func (c *Commands) GetIntentWriteModel(ctx context.Context, id, resourceOwner string) (*IDPIntentWriteModel, error) { + writeModel := NewIDPIntentWriteModel(id, resourceOwner) + err := c.eventstore.FilterToQueryReducer(ctx, writeModel) + if err != nil { + return nil, err + } + return writeModel, err +} + +// tokensForSucceededIDPIntent extracts the oidc.Tokens if available (and encrypts the access_token) for the succeeded event payload +func tokensForSucceededIDPIntent(session idp.Session, encryptionAlg crypto.EncryptionAlgorithm) (*crypto.CryptoValue, string, error) { + var tokens *oidc.Tokens[*oidc.IDTokenClaims] + switch s := session.(type) { + case *oauth.Session: + tokens = s.Tokens + case *openid.Session: + tokens = s.Tokens + case *jwt.Session: + tokens = s.Tokens + default: + return nil, "", nil + } + if tokens.Token == nil || tokens.AccessToken == "" { + return nil, tokens.IDToken, nil + } + accessToken, err := crypto.Encrypt([]byte(tokens.AccessToken), encryptionAlg) + return accessToken, tokens.IDToken, err +} diff --git a/internal/command/idp_intent_model.go b/internal/command/idp_intent_model.go new file mode 100644 index 0000000000..cd0cb6e8e0 --- /dev/null +++ b/internal/command/idp_intent_model.go @@ -0,0 +1,82 @@ +package command + +import ( + "net/url" + + "github.com/zitadel/zitadel/internal/crypto" + "github.com/zitadel/zitadel/internal/domain" + "github.com/zitadel/zitadel/internal/eventstore" + "github.com/zitadel/zitadel/internal/repository/idpintent" +) + +type IDPIntentWriteModel struct { + eventstore.WriteModel + + SuccessURL *url.URL + FailureURL *url.URL + IDPID string + IDPUser []byte + IDPAccessToken *crypto.CryptoValue + IDPIDToken string + UserID string + + State domain.IDPIntentState + aggregate *eventstore.Aggregate +} + +func NewIDPIntentWriteModel(id, resourceOwner string) *IDPIntentWriteModel { + return &IDPIntentWriteModel{ + WriteModel: eventstore.WriteModel{ + AggregateID: id, + ResourceOwner: resourceOwner, + }, + aggregate: &idpintent.NewAggregate(id, resourceOwner).Aggregate, + } +} + +func (wm *IDPIntentWriteModel) Reduce() error { + for _, event := range wm.Events { + switch e := event.(type) { + case *idpintent.StartedEvent: + wm.reduceStartedEvent(e) + case *idpintent.SucceededEvent: + wm.reduceSucceededEvent(e) + case *idpintent.FailedEvent: + wm.reduceFailedEvent(e) + } + } + return wm.WriteModel.Reduce() +} + +func (wm *IDPIntentWriteModel) Query() *eventstore.SearchQueryBuilder { + return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent). + ResourceOwner(wm.ResourceOwner). + AddQuery(). + AggregateTypes(idpintent.AggregateType). + AggregateIDs(wm.AggregateID). + EventTypes( + idpintent.StartedEventType, + idpintent.SucceededEventType, + idpintent.FailedEventType, + ). + Builder() +} + +func (wm *IDPIntentWriteModel) reduceStartedEvent(e *idpintent.StartedEvent) { + wm.SuccessURL = e.SuccessURL + wm.FailureURL = e.FailureURL + wm.IDPID = e.IDPID + wm.State = domain.IDPIntentStateStarted +} + +func (wm *IDPIntentWriteModel) reduceSucceededEvent(e *idpintent.SucceededEvent) { + wm.UserID = e.UserID + wm.IDPUser = e.IDPUser + wm.IDPAccessToken = e.IDPAccessToken + wm.IDPIDToken = e.IDPIDToken + wm.State = domain.IDPIntentStateSucceeded +} + +func (wm *IDPIntentWriteModel) reduceFailedEvent(e *idpintent.FailedEvent) { + wm.State = domain.IDPIntentStateFailed +} diff --git a/internal/command/idp_intent_test.go b/internal/command/idp_intent_test.go new file mode 100644 index 0000000000..a0be850fbc --- /dev/null +++ b/internal/command/idp_intent_test.go @@ -0,0 +1,667 @@ +package command + +import ( + "context" + "net/url" + "testing" + + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/zitadel/oidc/v2/pkg/oidc" + "golang.org/x/oauth2" + + "github.com/zitadel/zitadel/internal/api/authz" + "github.com/zitadel/zitadel/internal/crypto" + "github.com/zitadel/zitadel/internal/domain" + z_errors "github.com/zitadel/zitadel/internal/errors" + "github.com/zitadel/zitadel/internal/eventstore" + "github.com/zitadel/zitadel/internal/id" + "github.com/zitadel/zitadel/internal/id/mock" + "github.com/zitadel/zitadel/internal/idp" + "github.com/zitadel/zitadel/internal/idp/providers/jwt" + "github.com/zitadel/zitadel/internal/idp/providers/ldap" + "github.com/zitadel/zitadel/internal/idp/providers/oauth" + openid "github.com/zitadel/zitadel/internal/idp/providers/oidc" + rep_idp "github.com/zitadel/zitadel/internal/repository/idp" + "github.com/zitadel/zitadel/internal/repository/idpintent" + "github.com/zitadel/zitadel/internal/repository/instance" +) + +func TestCommands_CreateIntent(t *testing.T) { + type fields struct { + eventstore *eventstore.Eventstore + idGenerator id.Generator + } + type args struct { + ctx context.Context + idpID string + successURL string + failureURL string + resourceOwner string + } + type res struct { + intentID string + details *domain.ObjectDetails + err error + } + tests := []struct { + name string + fields fields + args args + res res + }{ + { + "error no id generator", + fields{ + eventstore: eventstoreExpect(t), + idGenerator: mock.NewIDGeneratorExpectError(t, z_errors.ThrowInternal(nil, "", "error id")), + }, + args{ + ctx: authz.SetCtxData(context.Background(), authz.CtxData{OrgID: "ro"}), + idpID: "", + successURL: "https://success.url", + failureURL: "https://failure.url", + }, + res{ + err: z_errors.ThrowInternal(nil, "", "error id"), + }, + }, + { + "error no idpID", + fields{ + eventstore: eventstoreExpect(t), + idGenerator: mock.ExpectID(t, "id"), + }, + args{ + ctx: authz.SetCtxData(context.Background(), authz.CtxData{OrgID: "ro"}), + idpID: "", + successURL: "https://success.url", + failureURL: "https://failure.url", + }, + res{ + err: z_errors.ThrowInvalidArgument(nil, "COMMAND-x8j2bk", "Errors.Intent.IDPMissing"), + }, + }, + { + "error no successURL", + fields{ + eventstore: eventstoreExpect(t), + idGenerator: mock.ExpectID(t, "id"), + }, + args{ + ctx: authz.SetCtxData(context.Background(), authz.CtxData{OrgID: "ro"}), + idpID: "idp", + successURL: ":", + failureURL: "https://failure.url", + }, + res{ + err: z_errors.ThrowInvalidArgument(nil, "COMMAND-x8j3bk", "Errors.Intent.SuccessURLMissing"), + }, + }, + { + "error no failureURL", + fields{ + eventstore: eventstoreExpect(t), + idGenerator: mock.ExpectID(t, "id"), + }, + args{ + ctx: authz.SetCtxData(context.Background(), authz.CtxData{OrgID: "ro"}), + idpID: "idp", + successURL: "https://success.url", + failureURL: ":", + }, + res{ + err: z_errors.ThrowInvalidArgument(nil, "COMMAND-x8j4bk", "Errors.Intent.FailureURLMissing"), + }, + }, + { + "error idp not existing", + fields{ + eventstore: eventstoreExpect(t, + expectFilter(), + expectFilter(), + expectFilter(), + ), + idGenerator: mock.ExpectID(t, "id"), + }, + args{ + ctx: authz.SetCtxData(context.Background(), authz.CtxData{OrgID: "ro"}), + idpID: "idp", + successURL: "https://success.url", + failureURL: "https://failure.url", + }, + res{ + err: z_errors.ThrowPreconditionFailed(nil, "COMMAND-39n221fs", "Errors.IDPConfig.NotExisting"), + }, + }, + { + "push", + fields{ + eventstore: eventstoreExpect(t, + expectFilter(), + expectFilter(), + expectFilter( + eventFromEventPusher( + instance.NewOAuthIDPAddedEvent(context.Background(), &instance.NewAggregate("ro").Aggregate, + "idp", + "name", + "clientID", + &crypto.CryptoValue{ + CryptoType: crypto.TypeEncryption, + Algorithm: "enc", + KeyID: "id", + Crypted: []byte("clientSecret"), + }, + "auth", + "token", + "user", + "idAttribute", + nil, + rep_idp.Options{}, + )), + ), + expectPush( + eventPusherToEvents( + func() eventstore.Command { + success, _ := url.Parse("https://success.url") + failure, _ := url.Parse("https://failure.url") + return idpintent.NewStartedEvent( + context.Background(), + &idpintent.NewAggregate("id", "ro").Aggregate, + success, + failure, + "idp", + ) + }(), + ), + ), + ), + idGenerator: mock.ExpectID(t, "id"), + }, + args{ + ctx: context.Background(), + resourceOwner: "ro", + idpID: "idp", + successURL: "https://success.url", + failureURL: "https://failure.url", + }, + res{ + intentID: "id", + details: &domain.ObjectDetails{ResourceOwner: "ro"}, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := &Commands{ + eventstore: tt.fields.eventstore, + idGenerator: tt.fields.idGenerator, + } + intentID, details, err := c.CreateIntent(tt.args.ctx, tt.args.idpID, tt.args.successURL, tt.args.failureURL, tt.args.resourceOwner) + require.ErrorIs(t, err, tt.res.err) + assert.Equal(t, tt.res.intentID, intentID) + assert.Equal(t, tt.res.details, details) + }) + } +} + +func TestCommands_AuthURLFromProvider(t *testing.T) { + type fields struct { + eventstore *eventstore.Eventstore + secretCrypto crypto.EncryptionAlgorithm + } + type args struct { + ctx context.Context + idpID string + state string + callbackURL string + } + type res struct { + authURL string + err error + } + tests := []struct { + name string + fields fields + args args + res res + }{ + { + "idp not existing", + fields{ + secretCrypto: crypto.CreateMockEncryptionAlg(gomock.NewController(t)), + eventstore: eventstoreExpect(t, + expectFilter(), + ), + }, + args{ + ctx: authz.SetCtxData(context.Background(), authz.CtxData{OrgID: "ro"}), + idpID: "idp", + state: "state", + callbackURL: "url", + }, + res{ + err: z_errors.ThrowPreconditionFailed(nil, "", ""), + }, + }, + { + "idp removed", + fields{ + secretCrypto: crypto.CreateMockEncryptionAlg(gomock.NewController(t)), + eventstore: eventstoreExpect(t, + expectFilter( + eventFromEventPusherWithInstanceID( + "instance", + instance.NewOAuthIDPAddedEvent(context.Background(), &instance.NewAggregate("instance").Aggregate, + "idp", + "name", + "clientID", + &crypto.CryptoValue{ + CryptoType: crypto.TypeEncryption, + Algorithm: "enc", + KeyID: "id", + Crypted: []byte("clientSecret"), + }, + "auth", + "token", + "user", + "idAttribute", + nil, + rep_idp.Options{}, + )), + eventFromEventPusherWithInstanceID( + "instance", + instance.NewIDPRemovedEvent(context.Background(), &instance.NewAggregate("instance").Aggregate, + "idp", + ), + ), + ), + ), + }, + args{ + ctx: authz.SetCtxData(context.Background(), authz.CtxData{OrgID: "ro"}), + idpID: "idp", + state: "state", + callbackURL: "url", + }, + res{ + err: z_errors.ThrowInternal(nil, "COMMAND-xw921211", "Errors.IDPConfig.NotExisting"), + }, + }, + { + "push", + fields{ + secretCrypto: crypto.CreateMockEncryptionAlg(gomock.NewController(t)), + eventstore: eventstoreExpect(t, + expectFilter( + eventFromEventPusherWithInstanceID( + "instance", + instance.NewOAuthIDPAddedEvent(context.Background(), &instance.NewAggregate("instance").Aggregate, + "idp", + "name", + "clientID", + &crypto.CryptoValue{ + CryptoType: crypto.TypeEncryption, + Algorithm: "enc", + KeyID: "id", + Crypted: []byte("clientSecret"), + }, + "auth", + "token", + "user", + "idAttribute", + nil, + rep_idp.Options{}, + )), + ), + expectFilter( + eventFromEventPusherWithInstanceID( + "instance", + instance.NewOAuthIDPAddedEvent(context.Background(), &instance.NewAggregate("instance").Aggregate, + "idp", + "name", + "clientID", + &crypto.CryptoValue{ + CryptoType: crypto.TypeEncryption, + Algorithm: "enc", + KeyID: "id", + Crypted: []byte("clientSecret"), + }, + "auth", + "token", + "user", + "idAttribute", + nil, + rep_idp.Options{}, + )), + ), + ), + }, + args{ + ctx: authz.SetCtxData(context.Background(), authz.CtxData{OrgID: "ro"}), + idpID: "idp", + state: "state", + callbackURL: "url", + }, + res{ + authURL: "auth?client_id=clientID&prompt=select_account&redirect_uri=url&response_type=code&state=state", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := &Commands{ + eventstore: tt.fields.eventstore, + idpConfigEncryption: tt.fields.secretCrypto, + } + authURL, err := c.AuthURLFromProvider(tt.args.ctx, tt.args.idpID, tt.args.state, tt.args.callbackURL) + require.ErrorIs(t, err, tt.res.err) + assert.Equal(t, tt.res.authURL, authURL) + }) + } +} + +func TestCommands_SucceedIDPIntent(t *testing.T) { + type fields struct { + eventstore *eventstore.Eventstore + idpConfigEncryption crypto.EncryptionAlgorithm + } + type args struct { + ctx context.Context + writeModel *IDPIntentWriteModel + idpUser idp.User + idpSession idp.Session + userID string + } + type res struct { + token string + err error + } + tests := []struct { + name string + fields fields + args args + res res + }{ + { + "encryption fails", + fields{ + idpConfigEncryption: func() crypto.EncryptionAlgorithm { + m := crypto.NewMockEncryptionAlgorithm(gomock.NewController(t)) + m.EXPECT().Encrypt(gomock.Any()).Return(nil, z_errors.ThrowInternal(nil, "id", "encryption failed")) + return m + }(), + }, + args{ + ctx: context.Background(), + writeModel: NewIDPIntentWriteModel("id", "ro"), + }, + res{ + err: z_errors.ThrowInternal(nil, "id", "encryption failed"), + }, + }, + { + "token encryption fails", + fields{ + idpConfigEncryption: func() crypto.EncryptionAlgorithm { + m := crypto.NewMockEncryptionAlgorithm(gomock.NewController(t)) + m.EXPECT().Encrypt(gomock.Any()).DoAndReturn(func(value []byte) ([]byte, error) { + return value, nil + }) + m.EXPECT().Encrypt(gomock.Any()).Return(nil, z_errors.ThrowInternal(nil, "id", "encryption failed")) + return m + }(), + }, + args{ + ctx: context.Background(), + writeModel: NewIDPIntentWriteModel("id", "ro"), + idpSession: &oauth.Session{ + Tokens: &oidc.Tokens[*oidc.IDTokenClaims]{ + Token: &oauth2.Token{ + AccessToken: "accessToken", + }, + }, + }, + }, + res{ + err: z_errors.ThrowInternal(nil, "id", "encryption failed"), + }, + }, + { + "push", + fields{ + idpConfigEncryption: crypto.CreateMockEncryptionAlg(gomock.NewController(t)), + eventstore: eventstoreExpect(t, + expectPush( + eventPusherToEvents( + func() eventstore.Command { + event, _ := idpintent.NewSucceededEvent( + context.Background(), + &idpintent.NewAggregate("id", "ro").Aggregate, + []byte(`{"RawInfo":{"id":"id"}}`), + "", + &crypto.CryptoValue{ + CryptoType: crypto.TypeEncryption, + Algorithm: "enc", + KeyID: "id", + Crypted: []byte("accessToken"), + }, + "", + ) + return event + }(), + ), + ), + ), + }, + args{ + ctx: context.Background(), + writeModel: NewIDPIntentWriteModel("id", "ro"), + idpSession: &oauth.Session{ + Tokens: &oidc.Tokens[*oidc.IDTokenClaims]{ + Token: &oauth2.Token{ + AccessToken: "accessToken", + }, + }, + }, + idpUser: &oauth.UserMapper{ + RawInfo: map[string]interface{}{ + "id": "id", + }, + }, + }, + res{ + token: "aWQ", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := &Commands{ + eventstore: tt.fields.eventstore, + idpConfigEncryption: tt.fields.idpConfigEncryption, + } + got, err := c.SucceedIDPIntent(tt.args.ctx, tt.args.writeModel, tt.args.idpUser, tt.args.idpSession, tt.args.userID) + require.ErrorIs(t, err, tt.res.err) + assert.Equal(t, tt.res.token, got) + }) + } +} + +func TestCommands_FailIDPIntent(t *testing.T) { + type fields struct { + eventstore *eventstore.Eventstore + } + type args struct { + ctx context.Context + writeModel *IDPIntentWriteModel + reason string + } + type res struct { + err error + } + tests := []struct { + name string + fields fields + args args + res res + }{ + { + "push", + fields{ + eventstore: eventstoreExpect(t, + expectPush( + eventPusherToEvents( + idpintent.NewFailedEvent( + context.Background(), + &idpintent.NewAggregate("id", "ro").Aggregate, + "reason", + ), + ), + ), + ), + }, + args{ + ctx: context.Background(), + writeModel: NewIDPIntentWriteModel("id", "ro"), + reason: "reason", + }, + res{ + err: nil, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := &Commands{ + eventstore: tt.fields.eventstore, + } + err := c.FailIDPIntent(tt.args.ctx, tt.args.writeModel, tt.args.reason) + require.ErrorIs(t, err, tt.res.err) + }) + } +} + +func Test_tokensForSucceededIDPIntent(t *testing.T) { + type args struct { + session idp.Session + encryptionAlg crypto.EncryptionAlgorithm + } + type res struct { + accessToken *crypto.CryptoValue + idToken string + err error + } + tests := []struct { + name string + args args + res res + }{ + { + "no tokens", + args{ + &ldap.Session{}, + crypto.CreateMockEncryptionAlg(gomock.NewController(t)), + }, + res{ + accessToken: nil, + idToken: "", + err: nil, + }, + }, + { + "token encryption fails", + args{ + &oauth.Session{ + Tokens: &oidc.Tokens[*oidc.IDTokenClaims]{ + Token: &oauth2.Token{ + AccessToken: "accessToken", + }, + }, + }, + func() crypto.EncryptionAlgorithm { + m := crypto.NewMockEncryptionAlgorithm(gomock.NewController(t)) + m.EXPECT().Encrypt(gomock.Any()).Return(nil, z_errors.ThrowInternal(nil, "id", "encryption failed")) + return m + }(), + }, + res{ + accessToken: nil, + idToken: "", + err: z_errors.ThrowInternal(nil, "id", "encryption failed"), + }, + }, + { + "oauth tokens", + args{ + &oauth.Session{ + Tokens: &oidc.Tokens[*oidc.IDTokenClaims]{ + Token: &oauth2.Token{ + AccessToken: "accessToken", + }, + }, + }, + crypto.CreateMockEncryptionAlg(gomock.NewController(t)), + }, + res{ + accessToken: &crypto.CryptoValue{ + CryptoType: crypto.TypeEncryption, + Algorithm: "enc", + KeyID: "id", + Crypted: []byte("accessToken"), + }, + idToken: "", + err: nil, + }, + }, + { + "oidc tokens", + args{ + &openid.Session{ + Tokens: &oidc.Tokens[*oidc.IDTokenClaims]{ + Token: &oauth2.Token{ + AccessToken: "accessToken", + }, + IDToken: "idToken", + }, + }, + crypto.CreateMockEncryptionAlg(gomock.NewController(t)), + }, + res{ + accessToken: &crypto.CryptoValue{ + CryptoType: crypto.TypeEncryption, + Algorithm: "enc", + KeyID: "id", + Crypted: []byte("accessToken"), + }, + idToken: "idToken", + err: nil, + }, + }, + { + "jwt tokens", + args{ + &jwt.Session{ + Tokens: &oidc.Tokens[*oidc.IDTokenClaims]{ + IDToken: "idToken", + }, + }, + crypto.CreateMockEncryptionAlg(gomock.NewController(t)), + }, + res{ + accessToken: nil, + idToken: "idToken", + err: nil, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gotAccessToken, gotIDToken, err := tokensForSucceededIDPIntent(tt.args.session, tt.args.encryptionAlg) + require.ErrorIs(t, err, tt.res.err) + assert.Equal(t, tt.res.accessToken, gotAccessToken) + assert.Equal(t, tt.res.idToken, gotIDToken) + }) + } +} diff --git a/internal/command/idp_model.go b/internal/command/idp_model.go index 2e098fecfd..036a08aa97 100644 --- a/internal/command/idp_model.go +++ b/internal/command/idp_model.go @@ -1,14 +1,31 @@ package command import ( + "net/http" "reflect" "time" + "github.com/zitadel/logging" + "github.com/zitadel/oidc/v2/pkg/client/rp" + "golang.org/x/oauth2" + "github.com/zitadel/zitadel/internal/crypto" "github.com/zitadel/zitadel/internal/domain" + "github.com/zitadel/zitadel/internal/errors" "github.com/zitadel/zitadel/internal/eventstore" + providers "github.com/zitadel/zitadel/internal/idp" + "github.com/zitadel/zitadel/internal/idp/providers/azuread" + "github.com/zitadel/zitadel/internal/idp/providers/github" + "github.com/zitadel/zitadel/internal/idp/providers/gitlab" + "github.com/zitadel/zitadel/internal/idp/providers/google" + "github.com/zitadel/zitadel/internal/idp/providers/jwt" + "github.com/zitadel/zitadel/internal/idp/providers/ldap" + "github.com/zitadel/zitadel/internal/idp/providers/oauth" + "github.com/zitadel/zitadel/internal/idp/providers/oidc" "github.com/zitadel/zitadel/internal/repository/idp" "github.com/zitadel/zitadel/internal/repository/idpconfig" + "github.com/zitadel/zitadel/internal/repository/instance" + "github.com/zitadel/zitadel/internal/repository/org" ) type OAuthIDPWriteModel struct { @@ -133,6 +150,45 @@ func (wm *OAuthIDPWriteModel) NewChanges( return changes, nil } +func (wm *OAuthIDPWriteModel) ToProvider(callbackURL string, idpAlg crypto.EncryptionAlgorithm) (providers.Provider, error) { + secret, err := crypto.DecryptString(wm.ClientSecret, idpAlg) + if err != nil { + return nil, err + } + config := &oauth2.Config{ + ClientID: wm.ClientID, + ClientSecret: secret, + Endpoint: oauth2.Endpoint{ + AuthURL: wm.AuthorizationEndpoint, + TokenURL: wm.TokenEndpoint, + }, + RedirectURL: callbackURL, + Scopes: wm.Scopes, + } + opts := make([]oauth.ProviderOpts, 0, 4) + if wm.IsCreationAllowed { + opts = append(opts, oauth.WithCreationAllowed()) + } + if wm.IsLinkingAllowed { + opts = append(opts, oauth.WithLinkingAllowed()) + } + if wm.IsAutoCreation { + opts = append(opts, oauth.WithAutoCreation()) + } + if wm.IsAutoUpdate { + opts = append(opts, oauth.WithAutoUpdate()) + } + return oauth.New( + config, + wm.Name, + wm.UserEndpoint, + func() providers.User { + return oauth.NewUserMapper(wm.IDAttribute) + }, + opts..., + ) +} + type OIDCIDPWriteModel struct { eventstore.WriteModel @@ -286,6 +342,40 @@ func (wm *OIDCIDPWriteModel) reduceOIDCConfigChangedEvent(e *idpconfig.OIDCConfi } } +func (wm *OIDCIDPWriteModel) ToProvider(callbackURL string, idpAlg crypto.EncryptionAlgorithm) (providers.Provider, error) { + secret, err := crypto.DecryptString(wm.ClientSecret, idpAlg) + if err != nil { + return nil, err + } + opts := make([]oidc.ProviderOpts, 1, 6) + opts[0] = oidc.WithSelectAccount() + if wm.IsIDTokenMapping { + opts = append(opts, oidc.WithIDTokenMapping()) + } + if wm.IsCreationAllowed { + opts = append(opts, oidc.WithCreationAllowed()) + } + if wm.IsLinkingAllowed { + opts = append(opts, oidc.WithLinkingAllowed()) + } + if wm.IsAutoCreation { + opts = append(opts, oidc.WithAutoCreation()) + } + if wm.IsAutoUpdate { + opts = append(opts, oidc.WithAutoUpdate()) + } + return oidc.New( + wm.Name, + wm.Issuer, + wm.ClientID, + secret, + callbackURL, + wm.Scopes, + oidc.DefaultMapper, + opts..., + ) +} + type JWTIDPWriteModel struct { eventstore.WriteModel @@ -423,6 +513,31 @@ func (wm *JWTIDPWriteModel) reduceJWTConfigChangedEvent(e *idpconfig.JWTConfigCh } } +func (wm *JWTIDPWriteModel) ToProvider(callbackURL string, idpAlg crypto.EncryptionAlgorithm) (providers.Provider, error) { + opts := make([]jwt.ProviderOpts, 0) + if wm.IsCreationAllowed { + opts = append(opts, jwt.WithCreationAllowed()) + } + if wm.IsLinkingAllowed { + opts = append(opts, jwt.WithLinkingAllowed()) + } + if wm.IsAutoCreation { + opts = append(opts, jwt.WithAutoCreation()) + } + if wm.IsAutoUpdate { + opts = append(opts, jwt.WithAutoUpdate()) + } + return jwt.New( + wm.Name, + wm.Issuer, + wm.JWTEndpoint, + wm.KeysEndpoint, + wm.HeaderName, + idpAlg, + opts..., + ) +} + type AzureADIDPWriteModel struct { eventstore.WriteModel @@ -527,6 +642,43 @@ func (wm *AzureADIDPWriteModel) NewChanges( } return changes, nil } +func (wm *AzureADIDPWriteModel) ToProvider(callbackURL string, idpAlg crypto.EncryptionAlgorithm) (providers.Provider, error) { + secret, err := crypto.DecryptString(wm.ClientSecret, idpAlg) + if err != nil { + return nil, err + } + opts := make([]azuread.ProviderOptions, 0, 3) + if wm.IsEmailVerified { + opts = append(opts, azuread.WithEmailVerified()) + } + if wm.Tenant != "" { + opts = append(opts, azuread.WithTenant(azuread.TenantType(wm.Tenant))) + } + oauthOpts := make([]oauth.ProviderOpts, 0, 4) + if wm.IsCreationAllowed { + oauthOpts = append(oauthOpts, oauth.WithCreationAllowed()) + } + if wm.IsLinkingAllowed { + oauthOpts = append(oauthOpts, oauth.WithLinkingAllowed()) + } + if wm.IsAutoCreation { + oauthOpts = append(oauthOpts, oauth.WithAutoCreation()) + } + if wm.IsAutoUpdate { + oauthOpts = append(oauthOpts, oauth.WithAutoUpdate()) + } + if len(oauthOpts) > 0 { + opts = append(opts, azuread.WithOAuthOptions(oauthOpts...)) + } + return azuread.New( + wm.Name, + wm.ClientID, + secret, + callbackURL, + wm.Scopes, + opts..., + ) +} type GitHubIDPWriteModel struct { eventstore.WriteModel @@ -614,6 +766,32 @@ func (wm *GitHubIDPWriteModel) NewChanges( } return changes, nil } +func (wm *GitHubIDPWriteModel) ToProvider(callbackURL string, idpAlg crypto.EncryptionAlgorithm) (providers.Provider, error) { + secret, err := crypto.DecryptString(wm.ClientSecret, idpAlg) + if err != nil { + return nil, err + } + oauthOpts := make([]oauth.ProviderOpts, 0, 4) + if wm.IsCreationAllowed { + oauthOpts = append(oauthOpts, oauth.WithCreationAllowed()) + } + if wm.IsLinkingAllowed { + oauthOpts = append(oauthOpts, oauth.WithLinkingAllowed()) + } + if wm.IsAutoCreation { + oauthOpts = append(oauthOpts, oauth.WithAutoCreation()) + } + if wm.IsAutoUpdate { + oauthOpts = append(oauthOpts, oauth.WithAutoUpdate()) + } + return github.New( + wm.ClientID, + secret, + callbackURL, + wm.Scopes, + oauthOpts..., + ) +} type GitHubEnterpriseIDPWriteModel struct { eventstore.WriteModel @@ -728,6 +906,37 @@ func (wm *GitHubEnterpriseIDPWriteModel) NewChanges( return changes, nil } +func (wm *GitHubEnterpriseIDPWriteModel) ToProvider(callbackURL string, idpAlg crypto.EncryptionAlgorithm) (providers.Provider, error) { + secret, err := crypto.DecryptString(wm.ClientSecret, idpAlg) + if err != nil { + return nil, err + } + oauthOpts := make([]oauth.ProviderOpts, 0, 4) + if wm.IsCreationAllowed { + oauthOpts = append(oauthOpts, oauth.WithCreationAllowed()) + } + if wm.IsLinkingAllowed { + oauthOpts = append(oauthOpts, oauth.WithLinkingAllowed()) + } + if wm.IsAutoCreation { + oauthOpts = append(oauthOpts, oauth.WithAutoCreation()) + } + if wm.IsAutoUpdate { + oauthOpts = append(oauthOpts, oauth.WithAutoUpdate()) + } + return github.NewCustomURL( + wm.Name, + wm.ClientID, + secret, + callbackURL, + wm.AuthorizationEndpoint, + wm.TokenEndpoint, + wm.UserEndpoint, + wm.Scopes, + oauthOpts..., + ) +} + type GitLabIDPWriteModel struct { eventstore.WriteModel @@ -815,6 +1024,33 @@ func (wm *GitLabIDPWriteModel) NewChanges( return changes, nil } +func (wm *GitLabIDPWriteModel) ToProvider(callbackURL string, idpAlg crypto.EncryptionAlgorithm) (providers.Provider, error) { + secret, err := crypto.DecryptString(wm.ClientSecret, idpAlg) + if err != nil { + return nil, err + } + opts := make([]oidc.ProviderOpts, 0, 4) + if wm.IsCreationAllowed { + opts = append(opts, oidc.WithCreationAllowed()) + } + if wm.IsLinkingAllowed { + opts = append(opts, oidc.WithLinkingAllowed()) + } + if wm.IsAutoCreation { + opts = append(opts, oidc.WithAutoCreation()) + } + if wm.IsAutoUpdate { + opts = append(opts, oidc.WithAutoUpdate()) + } + return gitlab.New( + wm.ClientID, + secret, + callbackURL, + wm.Scopes, + opts..., + ) +} + type GitLabSelfHostedIDPWriteModel struct { eventstore.WriteModel @@ -910,6 +1146,35 @@ func (wm *GitLabSelfHostedIDPWriteModel) NewChanges( return changes, nil } +func (wm *GitLabSelfHostedIDPWriteModel) ToProvider(callbackURL string, idpAlg crypto.EncryptionAlgorithm) (providers.Provider, error) { + secret, err := crypto.DecryptString(wm.ClientSecret, idpAlg) + if err != nil { + return nil, err + } + opts := make([]oidc.ProviderOpts, 0, 4) + if wm.IsCreationAllowed { + opts = append(opts, oidc.WithCreationAllowed()) + } + if wm.IsLinkingAllowed { + opts = append(opts, oidc.WithLinkingAllowed()) + } + if wm.IsAutoCreation { + opts = append(opts, oidc.WithAutoCreation()) + } + if wm.IsAutoUpdate { + opts = append(opts, oidc.WithAutoUpdate()) + } + return gitlab.NewCustomIssuer( + wm.Name, + wm.Issuer, + wm.ClientID, + secret, + callbackURL, + wm.Scopes, + opts..., + ) +} + type GoogleIDPWriteModel struct { eventstore.WriteModel @@ -997,6 +1262,38 @@ func (wm *GoogleIDPWriteModel) NewChanges( return changes, nil } +func (wm *GoogleIDPWriteModel) ToProvider(callbackURL string, idpAlg crypto.EncryptionAlgorithm) (providers.Provider, error) { + errorHandler := func(w http.ResponseWriter, r *http.Request, errorType string, errorDesc string, state string) { + logging.Errorf("token exchanged failed: %s - %s (state: %s)", errorType, errorType, state) + rp.DefaultErrorHandler(w, r, errorType, errorDesc, state) + } + oidc.WithRelyingPartyOption(rp.WithErrorHandler(errorHandler)) + secret, err := crypto.DecryptString(wm.ClientSecret, idpAlg) + if err != nil { + return nil, err + } + opts := make([]oidc.ProviderOpts, 0, 4) + if wm.IsCreationAllowed { + opts = append(opts, oidc.WithCreationAllowed()) + } + if wm.IsLinkingAllowed { + opts = append(opts, oidc.WithLinkingAllowed()) + } + if wm.IsAutoCreation { + opts = append(opts, oidc.WithAutoCreation()) + } + if wm.IsAutoUpdate { + opts = append(opts, oidc.WithAutoUpdate()) + } + return google.New( + wm.ClientID, + secret, + callbackURL, + wm.Scopes, + opts..., + ) +} + type LDAPIDPWriteModel struct { eventstore.WriteModel @@ -1157,6 +1454,81 @@ func (wm *LDAPIDPWriteModel) NewChanges( return changes, nil } +func (wm *LDAPIDPWriteModel) ToProvider(callbackURL string, idpAlg crypto.EncryptionAlgorithm) (providers.Provider, error) { + password, err := crypto.DecryptString(wm.BindPassword, idpAlg) + if err != nil { + return nil, err + } + var opts []ldap.ProviderOpts + if !wm.StartTLS { + opts = append(opts, ldap.WithoutStartTLS()) + } + if wm.LDAPAttributes.IDAttribute != "" { + opts = append(opts, ldap.WithCustomIDAttribute(wm.LDAPAttributes.IDAttribute)) + } + if wm.LDAPAttributes.FirstNameAttribute != "" { + opts = append(opts, ldap.WithFirstNameAttribute(wm.LDAPAttributes.FirstNameAttribute)) + } + if wm.LDAPAttributes.LastNameAttribute != "" { + opts = append(opts, ldap.WithLastNameAttribute(wm.LDAPAttributes.LastNameAttribute)) + } + if wm.LDAPAttributes.DisplayNameAttribute != "" { + opts = append(opts, ldap.WithDisplayNameAttribute(wm.LDAPAttributes.DisplayNameAttribute)) + } + if wm.LDAPAttributes.NickNameAttribute != "" { + opts = append(opts, ldap.WithNickNameAttribute(wm.LDAPAttributes.NickNameAttribute)) + } + if wm.LDAPAttributes.PreferredUsernameAttribute != "" { + opts = append(opts, ldap.WithPreferredUsernameAttribute(wm.LDAPAttributes.PreferredUsernameAttribute)) + } + if wm.LDAPAttributes.EmailAttribute != "" { + opts = append(opts, ldap.WithEmailAttribute(wm.LDAPAttributes.EmailAttribute)) + } + if wm.LDAPAttributes.EmailVerifiedAttribute != "" { + opts = append(opts, ldap.WithEmailVerifiedAttribute(wm.LDAPAttributes.EmailVerifiedAttribute)) + } + if wm.LDAPAttributes.PhoneAttribute != "" { + opts = append(opts, ldap.WithPhoneAttribute(wm.LDAPAttributes.PhoneAttribute)) + } + if wm.LDAPAttributes.PhoneVerifiedAttribute != "" { + opts = append(opts, ldap.WithPhoneVerifiedAttribute(wm.LDAPAttributes.PhoneVerifiedAttribute)) + } + if wm.LDAPAttributes.PreferredLanguageAttribute != "" { + opts = append(opts, ldap.WithPreferredLanguageAttribute(wm.LDAPAttributes.PreferredLanguageAttribute)) + } + if wm.LDAPAttributes.AvatarURLAttribute != "" { + opts = append(opts, ldap.WithAvatarURLAttribute(wm.LDAPAttributes.AvatarURLAttribute)) + } + if wm.LDAPAttributes.ProfileAttribute != "" { + opts = append(opts, ldap.WithProfileAttribute(wm.LDAPAttributes.ProfileAttribute)) + } + if wm.IsCreationAllowed { + opts = append(opts, ldap.WithCreationAllowed()) + } + if wm.IsLinkingAllowed { + opts = append(opts, ldap.WithLinkingAllowed()) + } + if wm.IsAutoCreation { + opts = append(opts, ldap.WithAutoCreation()) + } + if wm.IsAutoUpdate { + opts = append(opts, ldap.WithAutoUpdate()) + } + return ldap.New( + wm.Name, + wm.Servers, + wm.BaseDN, + wm.BindDN, + password, + wm.UserBase, + wm.UserObjectClasses, + wm.UserFilters, + wm.Timeout, + callbackURL, + opts..., + ), nil +} + type IDPRemoveWriteModel struct { eventstore.WriteModel @@ -1211,3 +1583,252 @@ func (wm *IDPRemoveWriteModel) reduceRemoved(id string) { } wm.State = domain.IDPStateRemoved } + +type IDPTypeWriteModel struct { + eventstore.WriteModel + + ID string + Type domain.IDPType + State domain.IDPState +} + +func NewIDPTypeWriteModel(id string) *IDPTypeWriteModel { + return &IDPTypeWriteModel{ + ID: id, + } +} + +func (wm *IDPTypeWriteModel) Reduce() error { + for _, event := range wm.Events { + switch e := event.(type) { + case *instance.OAuthIDPAddedEvent: + wm.reduceAdded(e.ID, domain.IDPTypeOAuth, e.Aggregate()) + case *org.OAuthIDPAddedEvent: + wm.reduceAdded(e.ID, domain.IDPTypeOAuth, e.Aggregate()) + case *instance.OIDCIDPAddedEvent: + wm.reduceAdded(e.ID, domain.IDPTypeOIDC, e.Aggregate()) + case *org.OIDCIDPAddedEvent: + wm.reduceAdded(e.ID, domain.IDPTypeOIDC, e.Aggregate()) + case *instance.JWTIDPAddedEvent: + wm.reduceAdded(e.ID, domain.IDPTypeJWT, e.Aggregate()) + case *org.JWTIDPAddedEvent: + wm.reduceAdded(e.ID, domain.IDPTypeJWT, e.Aggregate()) + case *instance.AzureADIDPAddedEvent: + wm.reduceAdded(e.ID, domain.IDPTypeAzureAD, e.Aggregate()) + case *org.AzureADIDPAddedEvent: + wm.reduceAdded(e.ID, domain.IDPTypeAzureAD, e.Aggregate()) + case *instance.GitHubIDPAddedEvent: + wm.reduceAdded(e.ID, domain.IDPTypeGitHub, e.Aggregate()) + case *org.GitHubIDPAddedEvent: + wm.reduceAdded(e.ID, domain.IDPTypeGitHub, e.Aggregate()) + case *instance.GitHubEnterpriseIDPAddedEvent: + wm.reduceAdded(e.ID, domain.IDPTypeGitHubEnterprise, e.Aggregate()) + case *org.GitHubEnterpriseIDPAddedEvent: + wm.reduceAdded(e.ID, domain.IDPTypeGitHubEnterprise, e.Aggregate()) + case *instance.GitLabIDPAddedEvent: + wm.reduceAdded(e.ID, domain.IDPTypeGitLab, e.Aggregate()) + case *org.GitLabIDPAddedEvent: + wm.reduceAdded(e.ID, domain.IDPTypeGitLab, e.Aggregate()) + case *instance.GitLabSelfHostedIDPAddedEvent: + wm.reduceAdded(e.ID, domain.IDPTypeGitLabSelfHosted, e.Aggregate()) + case *org.GitLabSelfHostedIDPAddedEvent: + wm.reduceAdded(e.ID, domain.IDPTypeGitLabSelfHosted, e.Aggregate()) + case *instance.GoogleIDPAddedEvent: + wm.reduceAdded(e.ID, domain.IDPTypeGoogle, e.Aggregate()) + case *org.GoogleIDPAddedEvent: + wm.reduceAdded(e.ID, domain.IDPTypeGoogle, e.Aggregate()) + case *instance.LDAPIDPAddedEvent: + wm.reduceAdded(e.ID, domain.IDPTypeLDAP, e.Aggregate()) + case *org.LDAPIDPAddedEvent: + wm.reduceAdded(e.ID, domain.IDPTypeLDAP, e.Aggregate()) + case *instance.IDPRemovedEvent: + wm.reduceRemoved(e.ID) + case *org.IDPRemovedEvent: + wm.reduceRemoved(e.ID) + case *instance.IDPConfigAddedEvent: + if e.Typ == domain.IDPConfigTypeOIDC { + wm.reduceAdded(e.ConfigID, domain.IDPTypeOIDC, e.Aggregate()) + } else if e.Typ == domain.IDPConfigTypeJWT { + wm.reduceAdded(e.ConfigID, domain.IDPTypeJWT, e.Aggregate()) + } + case *org.IDPConfigAddedEvent: + if e.Typ == domain.IDPConfigTypeOIDC { + wm.reduceAdded(e.ConfigID, domain.IDPTypeOIDC, e.Aggregate()) + } else if e.Typ == domain.IDPConfigTypeJWT { + wm.reduceAdded(e.ConfigID, domain.IDPTypeJWT, e.Aggregate()) + } + case *instance.IDPConfigRemovedEvent: + wm.reduceRemoved(e.ConfigID) + case *org.IDPConfigRemovedEvent: + wm.reduceRemoved(e.ConfigID) + } + } + return wm.WriteModel.Reduce() +} + +func (wm *IDPTypeWriteModel) reduceAdded(id string, t domain.IDPType, agg eventstore.Aggregate) { + if wm.ID != id { + return + } + wm.Type = t + wm.State = domain.IDPStateActive + wm.ResourceOwner = agg.ResourceOwner + wm.InstanceID = agg.InstanceID +} + +func (wm *IDPTypeWriteModel) reduceRemoved(id string) { + if wm.ID != id { + return + } + wm.Type = domain.IDPTypeUnspecified + wm.State = domain.IDPStateRemoved + wm.ResourceOwner = "" + wm.InstanceID = "" +} + +func (wm *IDPTypeWriteModel) Query() *eventstore.SearchQueryBuilder { + return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent). + AddQuery(). + AggregateTypes(instance.AggregateType). + EventTypes( + instance.OAuthIDPAddedEventType, + instance.OIDCIDPAddedEventType, + instance.JWTIDPAddedEventType, + instance.AzureADIDPAddedEventType, + instance.GitHubIDPAddedEventType, + instance.GitHubEnterpriseIDPAddedEventType, + instance.GitLabIDPAddedEventType, + instance.GitLabSelfHostedIDPAddedEventType, + instance.GoogleIDPAddedEventType, + instance.LDAPIDPAddedEventType, + instance.IDPRemovedEventType, + ). + EventData(map[string]interface{}{"id": wm.ID}). + Or(). + AggregateTypes(org.AggregateType). + EventTypes( + org.OAuthIDPAddedEventType, + org.OIDCIDPAddedEventType, + org.JWTIDPAddedEventType, + org.AzureADIDPAddedEventType, + org.GitHubIDPAddedEventType, + org.GitHubEnterpriseIDPAddedEventType, + org.GitLabIDPAddedEventType, + org.GitLabSelfHostedIDPAddedEventType, + org.GoogleIDPAddedEventType, + org.LDAPIDPAddedEventType, + org.IDPRemovedEventType, + ). + EventData(map[string]interface{}{"id": wm.ID}). + Or(). // old events + AggregateTypes(instance.AggregateType). + EventTypes( + instance.IDPConfigAddedEventType, + instance.IDPConfigRemovedEventType, + ). + EventData(map[string]interface{}{"idpConfigId": wm.ID}). + Or(). + AggregateTypes(org.AggregateType). + EventTypes( + org.IDPConfigAddedEventType, + org.IDPConfigRemovedEventType, + ). + EventData(map[string]interface{}{"idpConfigId": wm.ID}). + Builder() +} + +type IDP interface { + eventstore.QueryReducer + ToProvider(string, crypto.EncryptionAlgorithm) (providers.Provider, error) +} + +type AllIDPWriteModel struct { + model IDP + + ID string + IDPType domain.IDPType + ResourceOwner string + Instance bool +} + +func NewAllIDPWriteModel(resourceOwner string, instanceBool bool, id string, idpType domain.IDPType) (*AllIDPWriteModel, error) { + writeModel := &AllIDPWriteModel{ + ID: id, + IDPType: idpType, + ResourceOwner: resourceOwner, + Instance: instanceBool, + } + + if instanceBool { + switch idpType { + case domain.IDPTypeOIDC: + writeModel.model = NewOIDCInstanceIDPWriteModel(resourceOwner, id) + case domain.IDPTypeJWT: + writeModel.model = NewJWTInstanceIDPWriteModel(resourceOwner, id) + case domain.IDPTypeOAuth: + writeModel.model = NewOAuthInstanceIDPWriteModel(resourceOwner, id) + case domain.IDPTypeLDAP: + writeModel.model = NewLDAPInstanceIDPWriteModel(resourceOwner, id) + case domain.IDPTypeAzureAD: + writeModel.model = NewAzureADInstanceIDPWriteModel(resourceOwner, id) + case domain.IDPTypeGitHub: + writeModel.model = NewGitHubInstanceIDPWriteModel(resourceOwner, id) + case domain.IDPTypeGitHubEnterprise: + writeModel.model = NewGitHubEnterpriseInstanceIDPWriteModel(resourceOwner, id) + case domain.IDPTypeGitLab: + writeModel.model = NewGitLabInstanceIDPWriteModel(resourceOwner, id) + case domain.IDPTypeGitLabSelfHosted: + writeModel.model = NewGitLabSelfHostedInstanceIDPWriteModel(resourceOwner, id) + case domain.IDPTypeGoogle: + writeModel.model = NewGoogleInstanceIDPWriteModel(resourceOwner, id) + case domain.IDPTypeUnspecified: + fallthrough + default: + return nil, errors.ThrowInternal(nil, "COMMAND-xw921211", "Errors.IDPConfig.NotExisting") + } + } else { + switch idpType { + case domain.IDPTypeOIDC: + writeModel.model = NewOIDCOrgIDPWriteModel(resourceOwner, id) + case domain.IDPTypeJWT: + writeModel.model = NewJWTOrgIDPWriteModel(resourceOwner, id) + case domain.IDPTypeOAuth: + writeModel.model = NewOAuthOrgIDPWriteModel(resourceOwner, id) + case domain.IDPTypeLDAP: + writeModel.model = NewLDAPOrgIDPWriteModel(resourceOwner, id) + case domain.IDPTypeAzureAD: + writeModel.model = NewAzureADOrgIDPWriteModel(resourceOwner, id) + case domain.IDPTypeGitHub: + writeModel.model = NewGitHubOrgIDPWriteModel(resourceOwner, id) + case domain.IDPTypeGitHubEnterprise: + writeModel.model = NewGitHubEnterpriseOrgIDPWriteModel(resourceOwner, id) + case domain.IDPTypeGitLab: + writeModel.model = NewGitLabOrgIDPWriteModel(resourceOwner, id) + case domain.IDPTypeGitLabSelfHosted: + writeModel.model = NewGitLabSelfHostedOrgIDPWriteModel(resourceOwner, id) + case domain.IDPTypeGoogle: + writeModel.model = NewGoogleOrgIDPWriteModel(resourceOwner, id) + case domain.IDPTypeUnspecified: + fallthrough + default: + return nil, errors.ThrowInternal(nil, "COMMAND-xw921111", "Errors.IDPConfig.NotExisting") + } + } + return writeModel, nil +} + +func (wm *AllIDPWriteModel) Reduce() error { + return wm.model.Reduce() +} + +func (wm *AllIDPWriteModel) Query() *eventstore.SearchQueryBuilder { + return wm.model.Query() +} + +func (wm *AllIDPWriteModel) AppendEvents(events ...eventstore.Event) { + wm.model.AppendEvents(events...) +} + +func (wm *AllIDPWriteModel) ToProvider(callbackURL string, idpAlg crypto.EncryptionAlgorithm) (providers.Provider, error) { + return wm.model.ToProvider(callbackURL, idpAlg) +} diff --git a/internal/command/idp_model_test.go b/internal/command/idp_model_test.go new file mode 100644 index 0000000000..86626d4b42 --- /dev/null +++ b/internal/command/idp_model_test.go @@ -0,0 +1,323 @@ +package command + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/zitadel/zitadel/internal/domain" + "github.com/zitadel/zitadel/internal/errors" +) + +func TestCommands_AllIDPWriteModel(t *testing.T) { + type args struct { + resourceOwner string + instanceBool bool + id string + idpType domain.IDPType + } + type res struct { + writeModelType interface{} + err error + } + tests := []struct { + name string + args args + res res + }{ + { + name: "writemodel instance oidc", + args: args{ + resourceOwner: "owner", + instanceBool: true, + id: "id", + idpType: domain.IDPTypeOIDC, + }, + res: res{ + writeModelType: &InstanceOIDCIDPWriteModel{}, + err: nil, + }, + }, + { + name: "writemodel instance jwt", + args: args{ + resourceOwner: "owner", + instanceBool: true, + id: "id", + idpType: domain.IDPTypeJWT, + }, + res: res{ + writeModelType: &InstanceJWTIDPWriteModel{}, + err: nil, + }, + }, + { + name: "writemodel instance oauth", + args: args{ + resourceOwner: "owner", + instanceBool: true, + id: "id", + idpType: domain.IDPTypeOAuth, + }, + res: res{ + writeModelType: &InstanceOAuthIDPWriteModel{}, + err: nil, + }, + }, + { + name: "writemodel instance ldap", + args: args{ + resourceOwner: "owner", + instanceBool: true, + id: "id", + idpType: domain.IDPTypeLDAP, + }, + res: res{ + writeModelType: &InstanceLDAPIDPWriteModel{}, + err: nil, + }, + }, + { + name: "writemodel instance azureAD", + args: args{ + resourceOwner: "owner", + instanceBool: true, + id: "id", + idpType: domain.IDPTypeAzureAD, + }, + res: res{ + writeModelType: &InstanceAzureADIDPWriteModel{}, + err: nil, + }, + }, + { + name: "writemodel instance github", + args: args{ + resourceOwner: "owner", + instanceBool: true, + id: "id", + idpType: domain.IDPTypeGitHub, + }, + res: res{ + writeModelType: &InstanceGitHubIDPWriteModel{}, + err: nil, + }, + }, + { + name: "writemodel instance github enterprise", + args: args{ + resourceOwner: "owner", + instanceBool: true, + id: "id", + idpType: domain.IDPTypeGitHubEnterprise, + }, + res: res{ + writeModelType: &InstanceGitHubEnterpriseIDPWriteModel{}, + err: nil, + }, + }, + { + name: "writemodel instance gitlab", + args: args{ + resourceOwner: "owner", + instanceBool: true, + id: "id", + idpType: domain.IDPTypeGitLab, + }, + res: res{ + writeModelType: &InstanceGitLabIDPWriteModel{}, + err: nil, + }, + }, + { + name: "writemodel instance gitlab self hosted", + args: args{ + resourceOwner: "owner", + instanceBool: true, + id: "id", + idpType: domain.IDPTypeGitLabSelfHosted, + }, + res: res{ + writeModelType: &InstanceGitLabSelfHostedIDPWriteModel{}, + err: nil, + }, + }, + { + name: "writemodel instance google", + args: args{ + resourceOwner: "owner", + instanceBool: true, + id: "id", + idpType: domain.IDPTypeGoogle, + }, + res: res{ + writeModelType: &InstanceGoogleIDPWriteModel{}, + err: nil, + }, + }, + { + name: "writemodel instance unspecified", + args: args{ + resourceOwner: "owner", + instanceBool: true, + id: "id", + idpType: domain.IDPTypeUnspecified, + }, + res: res{ + err: errors.ThrowInternal(nil, "COMMAND-xw921211", "Errors.IDPConfig.NotExisting"), + }, + }, + { + name: "writemodel org oidc", + args: args{ + resourceOwner: "owner", + instanceBool: false, + id: "id", + idpType: domain.IDPTypeOIDC, + }, + res: res{ + writeModelType: &OrgOIDCIDPWriteModel{}, + err: nil, + }, + }, + { + name: "writemodel org jwt", + args: args{ + resourceOwner: "owner", + instanceBool: false, + id: "id", + idpType: domain.IDPTypeJWT, + }, + res: res{ + writeModelType: &OrgJWTIDPWriteModel{}, + err: nil, + }, + }, + { + name: "writemodel org oauth", + args: args{ + resourceOwner: "owner", + instanceBool: false, + id: "id", + idpType: domain.IDPTypeOAuth, + }, + res: res{ + writeModelType: &OrgOAuthIDPWriteModel{}, + err: nil, + }, + }, + { + name: "writemodel org ldap", + args: args{ + resourceOwner: "owner", + instanceBool: false, + id: "id", + idpType: domain.IDPTypeLDAP, + }, + res: res{ + writeModelType: &OrgLDAPIDPWriteModel{}, + err: nil, + }, + }, + { + name: "writemodel org azureAD", + args: args{ + resourceOwner: "owner", + instanceBool: false, + id: "id", + idpType: domain.IDPTypeAzureAD, + }, + res: res{ + writeModelType: &OrgAzureADIDPWriteModel{}, + err: nil, + }, + }, + { + name: "writemodel org github", + args: args{ + resourceOwner: "owner", + instanceBool: false, + id: "id", + idpType: domain.IDPTypeGitHub, + }, + res: res{ + writeModelType: &OrgGitHubIDPWriteModel{}, + err: nil, + }, + }, + { + name: "writemodel org github enterprise", + args: args{ + resourceOwner: "owner", + instanceBool: false, + id: "id", + idpType: domain.IDPTypeGitHubEnterprise, + }, + res: res{ + writeModelType: &OrgGitHubEnterpriseIDPWriteModel{}, + err: nil, + }, + }, + { + name: "writemodel org gitlab", + args: args{ + resourceOwner: "owner", + instanceBool: false, + id: "id", + idpType: domain.IDPTypeGitLab, + }, + res: res{ + writeModelType: &OrgGitLabIDPWriteModel{}, + err: nil, + }, + }, + { + name: "writemodel org gitlab self hosted", + args: args{ + resourceOwner: "owner", + instanceBool: false, + id: "id", + idpType: domain.IDPTypeGitLabSelfHosted, + }, + res: res{ + writeModelType: &OrgGitLabSelfHostedIDPWriteModel{}, + err: nil, + }, + }, + { + name: "writemodel org google", + args: args{ + resourceOwner: "owner", + instanceBool: false, + id: "id", + idpType: domain.IDPTypeGoogle, + }, + res: res{ + writeModelType: &OrgGoogleIDPWriteModel{}, + err: nil, + }, + }, + { + name: "writemodel org unspecified", + args: args{ + resourceOwner: "owner", + instanceBool: false, + id: "id", + idpType: domain.IDPTypeUnspecified, + }, + res: res{ + err: errors.ThrowInternal(nil, "COMMAND-xw921111", "Errors.IDPConfig.NotExisting"), + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + wm, err := NewAllIDPWriteModel(tt.args.resourceOwner, tt.args.instanceBool, tt.args.id, tt.args.idpType) + require.ErrorIs(t, err, tt.res.err) + if wm != nil { + assert.IsType(t, tt.res.writeModelType, wm.model) + } + }) + } +} diff --git a/internal/command/main_test.go b/internal/command/main_test.go index 10fc1c2f6c..5c7b42d3a7 100644 --- a/internal/command/main_test.go +++ b/internal/command/main_test.go @@ -16,6 +16,7 @@ import ( "github.com/zitadel/zitadel/internal/eventstore/repository" "github.com/zitadel/zitadel/internal/eventstore/repository/mock" action_repo "github.com/zitadel/zitadel/internal/repository/action" + "github.com/zitadel/zitadel/internal/repository/idpintent" iam_repo "github.com/zitadel/zitadel/internal/repository/instance" key_repo "github.com/zitadel/zitadel/internal/repository/keypair" "github.com/zitadel/zitadel/internal/repository/org" @@ -41,6 +42,7 @@ func eventstoreExpect(t *testing.T, expects ...expect) *eventstore.Eventstore { key_repo.RegisterEventMappers(es) action_repo.RegisterEventMappers(es) session.RegisterEventMappers(es) + idpintent.RegisterEventMappers(es) return es } diff --git a/internal/command/user_human.go b/internal/command/user_human.go index 0bb075a345..061dc22329 100644 --- a/internal/command/user_human.go +++ b/internal/command/user_human.go @@ -58,6 +58,9 @@ type AddHuman struct { Register bool Metadata []*AddMetadataEntry + // Links are optional + Links []*AddLink + // Details are set after a successful execution of the command Details *domain.ObjectDetails @@ -65,6 +68,12 @@ type AddHuman struct { EmailCode *string } +type AddLink struct { + IDPID string + DisplayName string + IDPExternalID string +} + func (h *AddHuman) Validate() (err error) { if err := h.Email.Validate(); err != nil { return err @@ -226,6 +235,13 @@ func (c *Commands) AddHumanCommand(human *AddHuman, orgID string, passwordAlg cr metadataEntry.Value, )) } + for _, link := range human.Links { + cmd, err := addLink(ctx, filter, a, link) + if err != nil { + return nil, err + } + cmds = append(cmds, cmd) + } return cmds, nil }, nil @@ -260,6 +276,15 @@ func (c *Commands) addHumanCommandEmail(ctx context.Context, filter preparation. } return cmds, nil } + +func addLink(ctx context.Context, filter preparation.FilterToQueryReducer, a *user.Aggregate, link *AddLink) (eventstore.Command, error) { + exists, err := ExistsIDP(ctx, filter, link.IDPID, a.ResourceOwner) + if !exists || err != nil { + return nil, errors.ThrowPreconditionFailed(err, "COMMAND-39nf2", "Errors.IDPConfig.NotExisting") + } + return user.NewUserIDPLinkAddedEvent(ctx, &a.Aggregate, link.IDPID, link.DisplayName, link.IDPExternalID), nil +} + func (c *Commands) addHumanCommandPhone(ctx context.Context, filter preparation.FilterToQueryReducer, cmds []eventstore.Command, a *user.Aggregate, human *AddHuman, codeAlg crypto.EncryptionAlgorithm) ([]eventstore.Command, error) { if human.Phone.Number == "" { return cmds, nil diff --git a/internal/command/user_human_test.go b/internal/command/user_human_test.go index bfbe48ad56..5d6f131c27 100644 --- a/internal/command/user_human_test.go +++ b/internal/command/user_human_test.go @@ -31,7 +31,7 @@ func TestCommandSide_AddHuman(t *testing.T) { idGenerator id.Generator userPasswordAlg crypto.HashAlgorithm codeAlg crypto.EncryptionAlgorithm - newEmailCode func(ctx context.Context, filter preparation.FilterToQueryReducer, alg crypto.EncryptionAlgorithm) (*CryptoCodeWithExpiry, error) + newCode cryptoCodeFunc } type args struct { ctx context.Context @@ -446,7 +446,7 @@ func TestCommandSide_AddHuman(t *testing.T) { idGenerator: id_mock.NewIDGeneratorExpectIDs(t, "user1"), userPasswordAlg: crypto.CreateMockHashAlg(gomock.NewController(t)), codeAlg: crypto.CreateMockEncryptionAlg(gomock.NewController(t)), - newEmailCode: mockEmailCode("emailCode", time.Hour), + newCode: mockCode("emailCode", time.Hour), }, args: args{ ctx: context.Background(), @@ -526,7 +526,7 @@ func TestCommandSide_AddHuman(t *testing.T) { idGenerator: id_mock.NewIDGeneratorExpectIDs(t, "user1"), userPasswordAlg: crypto.CreateMockHashAlg(gomock.NewController(t)), codeAlg: crypto.CreateMockEncryptionAlg(gomock.NewController(t)), - newEmailCode: mockEmailCode("emailCode", time.Hour), + newCode: mockCode("emailCode", time.Hour), }, args: args{ ctx: context.Background(), @@ -1202,7 +1202,7 @@ func TestCommandSide_AddHuman(t *testing.T) { userPasswordAlg: tt.fields.userPasswordAlg, userEncryption: tt.fields.codeAlg, idGenerator: tt.fields.idGenerator, - newEmailCode: tt.fields.newEmailCode, + newCode: tt.fields.newCode, } err := r.AddHuman(tt.args.ctx, tt.args.orgID, tt.args.human, tt.args.allowInitMail) if tt.res.err == nil { @@ -3992,18 +3992,3 @@ func TestAddHumanCommand(t *testing.T) { }) } } - -func mockEmailCode(code string, exp time.Duration) func(ctx context.Context, filter preparation.FilterToQueryReducer, alg crypto.EncryptionAlgorithm) (*CryptoCodeWithExpiry, error) { - return func(ctx context.Context, filter preparation.FilterToQueryReducer, alg crypto.EncryptionAlgorithm) (*CryptoCodeWithExpiry, error) { - return &CryptoCodeWithExpiry{ - Crypted: &crypto.CryptoValue{ - CryptoType: crypto.TypeEncryption, - Algorithm: "enc", - KeyID: "id", - Crypted: []byte(code), - }, - Plain: code, - Expiry: exp, - }, nil - } -} diff --git a/internal/command/user_human_webauthn.go b/internal/command/user_human_webauthn.go index 2d9d8db7a8..5156b5f8f3 100644 --- a/internal/command/user_human_webauthn.go +++ b/internal/command/user_human_webauthn.go @@ -539,7 +539,7 @@ func (c *Commands) humanAddPasswordlessInitCode(ctx context.Context, userID, res } if !direct { codeEventCreator = func(ctx context.Context, agg *eventstore.Aggregate, id string, cryptoCode *crypto.CryptoValue, exp time.Duration) eventstore.Command { - return usr_repo.NewHumanPasswordlessInitCodeRequestedEvent(ctx, agg, id, cryptoCode, exp) + return usr_repo.NewHumanPasswordlessInitCodeRequestedEvent(ctx, agg, id, cryptoCode, exp, "", false) } } codeEvent := codeEventCreator(ctx, UserAggregateFromWriteModel(&initCode.WriteModel), codeID, cryptoCode, passwordlessCodeGenerator.Expiry()) diff --git a/internal/command/user_human_webauthn_model.go b/internal/command/user_human_webauthn_model.go index bbf61ee95e..b92e35dbd0 100644 --- a/internal/command/user_human_webauthn_model.go +++ b/internal/command/user_human_webauthn_model.go @@ -512,6 +512,9 @@ func (wm *HumanPasswordlessInitCodeWriteModel) appendRequestedEvent(e *user.Huma wm.CryptoCode = e.Code wm.Expiration = e.Expiry wm.State = domain.PasswordlessInitCodeStateRequested + if e.CodeReturned { + wm.State = domain.PasswordlessInitCodeStateActive + } } func (wm *HumanPasswordlessInitCodeWriteModel) appendCheckFailedEvent(e *user.HumanPasswordlessInitCodeCheckFailedEvent) { diff --git a/internal/command/user_idp_link.go b/internal/command/user_idp_link.go index 9db06bf6ab..4c03f46436 100644 --- a/internal/command/user_idp_link.go +++ b/internal/command/user_idp_link.go @@ -3,20 +3,25 @@ package command import ( "context" - "github.com/zitadel/zitadel/internal/eventstore" - + "github.com/zitadel/zitadel/internal/api/authz" "github.com/zitadel/zitadel/internal/domain" caos_errs "github.com/zitadel/zitadel/internal/errors" + "github.com/zitadel/zitadel/internal/eventstore" "github.com/zitadel/zitadel/internal/repository/user" "github.com/zitadel/zitadel/internal/telemetry/tracing" ) -func (c *Commands) AddUserIDPLink(ctx context.Context, userID, resourceOwner string, link *domain.UserIDPLink) (err error) { +func (c *Commands) AddUserIDPLink(ctx context.Context, userID, resourceOwner string, link *domain.UserIDPLink) (_ *domain.ObjectDetails, err error) { if userID == "" { - return caos_errs.ThrowInvalidArgument(nil, "COMMAND-03j8f", "Errors.IDMissing") + return nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-03j8f", "Errors.IDMissing") } if err := c.checkUserExists(ctx, userID, resourceOwner); err != nil { - return err + return nil, err + } + if userID != authz.GetCtxData(ctx).UserID { + if err := c.checkPermission(ctx, domain.PermissionUserWrite, resourceOwner, userID); err != nil { + return nil, err + } } linkWriteModel := NewUserIDPLinkWriteModel(userID, link.IDPConfigID, link.ExternalUserID, resourceOwner) @@ -24,11 +29,18 @@ func (c *Commands) AddUserIDPLink(ctx context.Context, userID, resourceOwner str event, err := c.addUserIDPLink(ctx, userAgg, link) if err != nil { - return err + return nil, err } - _, err = c.eventstore.Push(ctx, event) - return err + events, err := c.eventstore.Push(ctx, event) + if err != nil { + return nil, err + } + return &domain.ObjectDetails{ + Sequence: events[len(events)-1].Sequence(), + EventDate: events[len(events)-1].CreationDate(), + ResourceOwner: events[len(events)-1].Aggregate().ResourceOwner, + }, nil } func (c *Commands) BulkAddedUserIDPLinks(ctx context.Context, userID, resourceOwner string, links []*domain.UserIDPLink) (err error) { diff --git a/internal/command/user_v2_email_test.go b/internal/command/user_v2_email_test.go index af6478473d..dfcbe91070 100644 --- a/internal/command/user_v2_email_test.go +++ b/internal/command/user_v2_email_test.go @@ -199,7 +199,7 @@ func TestCommands_ChangeUserEmailURLTemplate(t *testing.T) { email: "email-changed@test.ch", urlTmpl: "{{", }, - wantErr: caos_errs.ThrowInvalidArgument(nil, "USERv2-ooD8p", "Errors.User.Email.InvalidURLTemplate"), + wantErr: caos_errs.ThrowInvalidArgument(nil, "DOMAIN-oGh5e", "Errors.User.InvalidURLTemplate"), }, { name: "permission missing", diff --git a/internal/command/user_v2_passkey.go b/internal/command/user_v2_passkey.go new file mode 100644 index 0000000000..2795e6df8a --- /dev/null +++ b/internal/command/user_v2_passkey.go @@ -0,0 +1,156 @@ +package command + +import ( + "context" + "io" + + "github.com/zitadel/logging" + + "github.com/zitadel/zitadel/internal/api/authz" + "github.com/zitadel/zitadel/internal/crypto" + "github.com/zitadel/zitadel/internal/domain" + caos_errs "github.com/zitadel/zitadel/internal/errors" + "github.com/zitadel/zitadel/internal/eventstore" + "github.com/zitadel/zitadel/internal/repository/user" +) + +// RegisterUserPasskey creates a passkey registration for the current authenticated user. +// UserID, ussualy taken from the request is compaired against the user ID in the context. +func (c *Commands) RegisterUserPasskey(ctx context.Context, userID, resourceOwner string, authenticator domain.AuthenticatorAttachment) (*domain.PasskeyRegistrationDetails, error) { + if err := authz.UserIDInCTX(ctx, userID); err != nil { + return nil, err + } + return c.registerUserPasskey(ctx, userID, resourceOwner, authenticator) +} + +// RegisterUserPasskeyWithCode registers a new passkey for a unauthenticated user id. +// The resource is protected by the code, identified by the codeID. +func (c *Commands) RegisterUserPasskeyWithCode(ctx context.Context, userID, resourceOwner string, authenticator domain.AuthenticatorAttachment, codeID, code string, alg crypto.EncryptionAlgorithm) (*domain.PasskeyRegistrationDetails, error) { + event, err := c.verifyUserPasskeyCode(ctx, userID, resourceOwner, codeID, code, alg) + if err != nil { + return nil, err + } + + return c.registerUserPasskey(ctx, userID, resourceOwner, authenticator, event) +} + +type eventCallback func(context.Context, *eventstore.Aggregate) eventstore.Command + +// verifyUserPasskeyCode verifies a passkey code, identified by codeID and userID. +// A code can only be used once. +// Upon success an event callback is returned, which must be called after +// all other events for the current request are created. +// This prevent consuming a code when another error occurred after verification. +func (c *Commands) verifyUserPasskeyCode(ctx context.Context, userID, resourceOwner, codeID, code string, alg crypto.EncryptionAlgorithm) (eventCallback, error) { + wm := NewHumanPasswordlessInitCodeWriteModel(userID, codeID, resourceOwner) + err := c.eventstore.FilterToQueryReducer(ctx, wm) + if err != nil { + return nil, err + } + err = verifyCryptoCode(ctx, c.eventstore.Filter, domain.SecretGeneratorTypePasswordlessInitCode, alg, wm.ChangeDate, wm.Expiration, wm.CryptoCode, code) + if err != nil || wm.State != domain.PasswordlessInitCodeStateActive { + c.verifyUserPasskeyCodeFailed(ctx, wm) + return nil, caos_errs.ThrowInvalidArgument(err, "COMMAND-Eeb2a", "Errors.User.Code.Invalid") + } + return func(ctx context.Context, userAgg *eventstore.Aggregate) eventstore.Command { + return user.NewHumanPasswordlessInitCodeCheckSucceededEvent(ctx, userAgg, codeID) + }, nil +} + +func (c *Commands) verifyUserPasskeyCodeFailed(ctx context.Context, wm *HumanPasswordlessInitCodeWriteModel) { + userAgg := UserAggregateFromWriteModel(&wm.WriteModel) + _, err := c.eventstore.Push(ctx, user.NewHumanPasswordlessInitCodeCheckFailedEvent(ctx, userAgg, wm.CodeID)) + logging.WithFields("userID", userAgg.ID).OnError(err).Error("RegisterUserPasskeyWithCode push failed") +} + +func (c *Commands) registerUserPasskey(ctx context.Context, userID, resourceOwner string, authenticator domain.AuthenticatorAttachment, events ...eventCallback) (*domain.PasskeyRegistrationDetails, error) { + wm, userAgg, webAuthN, err := c.createUserPasskey(ctx, userID, resourceOwner, authenticator) + if err != nil { + return nil, err + } + return c.pushUserPasskey(ctx, wm, userAgg, webAuthN, events...) +} + +func (c *Commands) createUserPasskey(ctx context.Context, userID, resourceOwner string, authenticator domain.AuthenticatorAttachment) (*HumanWebAuthNWriteModel, *eventstore.Aggregate, *domain.WebAuthNToken, error) { + passwordlessTokens, err := c.getHumanPasswordlessTokens(ctx, userID, resourceOwner) + if err != nil { + return nil, nil, nil, err + } + return c.addHumanWebAuthN(ctx, userID, resourceOwner, false, passwordlessTokens, authenticator, domain.UserVerificationRequirementRequired) +} + +func (c *Commands) pushUserPasskey(ctx context.Context, wm *HumanWebAuthNWriteModel, userAgg *eventstore.Aggregate, webAuthN *domain.WebAuthNToken, events ...eventCallback) (*domain.PasskeyRegistrationDetails, error) { + cmds := make([]eventstore.Command, len(events)+1) + cmds[0] = user.NewHumanPasswordlessAddedEvent(ctx, userAgg, wm.WebauthNTokenID, webAuthN.Challenge) + for i, event := range events { + cmds[i+1] = event(ctx, userAgg) + } + + err := c.pushAppendAndReduce(ctx, wm, cmds...) + if err != nil { + return nil, err + } + return &domain.PasskeyRegistrationDetails{ + ObjectDetails: writeModelToObjectDetails(&wm.WriteModel), + PasskeyID: wm.WebauthNTokenID, + PublicKeyCredentialCreationOptions: webAuthN.CredentialCreationData, + }, nil +} + +// AddUserPasskeyCode generates a Passkey code and sends an email +// with the default generated URL (pointing to zitadel). +func (c *Commands) AddUserPasskeyCode(ctx context.Context, userID, resourceOwner string, alg crypto.EncryptionAlgorithm) (*domain.ObjectDetails, error) { + details, err := c.addUserPasskeyCode(ctx, userID, resourceOwner, alg, "", false) + if err != nil { + return nil, err + } + return details.ObjectDetails, err +} + +// AddUserPasskeyCodeURLTemplate generates a Passkey code and sends an email +// with the URL created from passed template string. +// The template is executed as a test, before pushing to the eventstore. +func (c *Commands) AddUserPasskeyCodeURLTemplate(ctx context.Context, userID, resourceOwner string, alg crypto.EncryptionAlgorithm, urlTmpl string) (*domain.ObjectDetails, error) { + if err := domain.RenderPasskeyURLTemplate(io.Discard, urlTmpl, userID, resourceOwner, "codeID", "code"); err != nil { + return nil, err + } + details, err := c.addUserPasskeyCode(ctx, userID, resourceOwner, alg, urlTmpl, false) + if err != nil { + return nil, err + } + return details.ObjectDetails, err +} + +// AddUserPasskeyCodeReturn generates and returns a Passkey code. +// No email will be send to the user. +func (c *Commands) AddUserPasskeyCodeReturn(ctx context.Context, userID, resourceOwner string, alg crypto.EncryptionAlgorithm) (*domain.PasskeyCodeDetails, error) { + return c.addUserPasskeyCode(ctx, userID, resourceOwner, alg, "", true) +} + +func (c *Commands) addUserPasskeyCode(ctx context.Context, userID, resourceOwner string, alg crypto.EncryptionAlgorithm, urlTmpl string, returnCode bool) (*domain.PasskeyCodeDetails, error) { + codeID, err := c.idGenerator.Next() + if err != nil { + return nil, err + } + code, err := c.newCode(ctx, c.eventstore.Filter, domain.SecretGeneratorTypePasswordlessInitCode, alg) + if err != nil { + return nil, err + } + wm := NewHumanPasswordlessInitCodeWriteModel(userID, codeID, resourceOwner) + err = c.eventstore.FilterToQueryReducer(ctx, wm) + if err != nil { + return nil, err + } + agg := UserAggregateFromWriteModel(&wm.WriteModel) + + cmd := user.NewHumanPasswordlessInitCodeRequestedEvent(ctx, agg, codeID, code.Crypted, code.Expiry, urlTmpl, returnCode) + err = c.pushAppendAndReduce(ctx, wm, cmd) + if err != nil { + return nil, err + } + return &domain.PasskeyCodeDetails{ + ObjectDetails: writeModelToObjectDetails(&wm.WriteModel), + CodeID: codeID, + Code: code.Plain, + }, nil +} diff --git a/internal/command/user_v2_passkey_test.go b/internal/command/user_v2_passkey_test.go new file mode 100644 index 0000000000..aefa9685aa --- /dev/null +++ b/internal/command/user_v2_passkey_test.go @@ -0,0 +1,915 @@ +package command + +import ( + "context" + "io" + "testing" + "time" + + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "golang.org/x/text/language" + + "github.com/zitadel/zitadel/internal/api/authz" + "github.com/zitadel/zitadel/internal/crypto" + "github.com/zitadel/zitadel/internal/domain" + caos_errs "github.com/zitadel/zitadel/internal/errors" + "github.com/zitadel/zitadel/internal/eventstore" + "github.com/zitadel/zitadel/internal/eventstore/repository" + "github.com/zitadel/zitadel/internal/id" + id_mock "github.com/zitadel/zitadel/internal/id/mock" + "github.com/zitadel/zitadel/internal/repository/org" + "github.com/zitadel/zitadel/internal/repository/user" + webauthn_helper "github.com/zitadel/zitadel/internal/webauthn" +) + +func TestCommands_RegisterUserPasskey(t *testing.T) { + ctx := authz.NewMockContextWithPermissions("instance1", "org1", "user1", nil) + ctx = authz.WithRequestedDomain(ctx, "example.com") + + webauthnConfig := &webauthn_helper.Config{ + DisplayName: "test", + ExternalSecure: true, + } + userAgg := &user.NewAggregate("user1", "org1").Aggregate + type fields struct { + eventstore *eventstore.Eventstore + idGenerator id.Generator + } + type args struct { + userID string + resourceOwner string + authenticator domain.AuthenticatorAttachment + } + tests := []struct { + name string + fields fields + args args + want *domain.PasskeyRegistrationDetails + wantErr error + }{ + { + name: "wrong user", + args: args{ + userID: "foo", + resourceOwner: "org1", + authenticator: domain.AuthenticatorAttachmentCrossPlattform, + }, + wantErr: caos_errs.ThrowUnauthenticated(nil, "AUTH-Bohd2", "Errors.User.UserIDWrong"), + }, + { + name: "get human passwordless error", + fields: fields{ + eventstore: eventstoreExpect(t, + expectFilterError(io.ErrClosedPipe), + ), + }, + args: args{ + userID: "user1", + resourceOwner: "org1", + authenticator: domain.AuthenticatorAttachmentCrossPlattform, + }, + wantErr: io.ErrClosedPipe, + }, + { + name: "id generator error", + fields: fields{ + eventstore: eventstoreExpect(t, + expectFilter(), // getHumanPasswordlessTokens + expectFilter(eventFromEventPusher( + user.NewHumanAddedEvent(ctx, + userAgg, + "username", + "firstname", + "lastname", + "nickname", + "displayname", + language.German, + domain.GenderUnspecified, + "email@test.ch", + true, + ), + )), + expectFilter(eventFromEventPusher( + org.NewOrgAddedEvent(ctx, + &org.NewAggregate("org1").Aggregate, + "org1", + ), + )), + expectFilter(eventFromEventPusher( + org.NewDomainPolicyAddedEvent(ctx, + &org.NewAggregate("org1").Aggregate, + false, false, false, + ), + )), + ), + idGenerator: id_mock.NewIDGeneratorExpectError(t, io.ErrClosedPipe), + }, + args: args{ + userID: "user1", + resourceOwner: "org1", + authenticator: domain.AuthenticatorAttachmentCrossPlattform, + }, + wantErr: io.ErrClosedPipe, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := &Commands{ + eventstore: tt.fields.eventstore, + idGenerator: tt.fields.idGenerator, + webauthnConfig: webauthnConfig, + } + _, err := c.RegisterUserPasskey(ctx, tt.args.userID, tt.args.resourceOwner, tt.args.authenticator) + require.ErrorIs(t, err, tt.wantErr) + // successful case can't be tested due to random challenge. + }) + } +} + +func TestCommands_RegisterUserPasskeyWithCode(t *testing.T) { + ctx := authz.WithRequestedDomain(context.Background(), "example.com") + webauthnConfig := &webauthn_helper.Config{ + DisplayName: "test", + ExternalSecure: true, + } + alg := crypto.CreateMockEncryptionAlg(gomock.NewController(t)) + es := eventstoreExpect(t, + expectFilter(eventFromEventPusher(testSecretGeneratorAddedEvent(domain.SecretGeneratorTypePasswordlessInitCode))), + ) + code, err := newCryptoCodeWithExpiry(ctx, es.Filter, domain.SecretGeneratorTypePasswordlessInitCode, alg) + require.NoError(t, err) + userAgg := &user.NewAggregate("user1", "org1").Aggregate + type fields struct { + eventstore *eventstore.Eventstore + idGenerator id.Generator + } + type args struct { + userID string + resourceOwner string + authenticator domain.AuthenticatorAttachment + codeID string + code string + } + tests := []struct { + name string + fields fields + args args + wantErr error + }{ + { + name: "code verification error", + fields: fields{ + eventstore: eventstoreExpect(t, + expectFilter( + eventFromEventPusherWithCreationDateNow( + user.NewHumanPasswordlessInitCodeRequestedEvent(context.Background(), + userAgg, "123", code.Crypted, time.Minute, "", false, + ), + ), + eventFromEventPusherWithCreationDateNow( + user.NewHumanPasswordlessInitCodeSentEvent(ctx, userAgg, "123"), + ), + ), + expectFilter(eventFromEventPusher(testSecretGeneratorAddedEvent(domain.SecretGeneratorTypePasswordlessInitCode))), + expectPush([]*repository.Event{eventFromEventPusher( + user.NewHumanPasswordlessInitCodeCheckFailedEvent(ctx, userAgg, "123"), + )}), + ), + }, + args: args{ + userID: "user1", + resourceOwner: "org1", + authenticator: domain.AuthenticatorAttachmentCrossPlattform, + codeID: "123", + code: "wrong", + }, + wantErr: caos_errs.ThrowInvalidArgument(err, "COMMAND-Eeb2a", "Errors.User.Code.Invalid"), + }, + { + name: "code verification ok, get human passwordless error", + fields: fields{ + eventstore: eventstoreExpect(t, + expectFilter( + eventFromEventPusherWithCreationDateNow( + user.NewHumanPasswordlessInitCodeRequestedEvent(context.Background(), + userAgg, "123", code.Crypted, time.Minute, "", false, + ), + ), + eventFromEventPusherWithCreationDateNow( + user.NewHumanPasswordlessInitCodeSentEvent(ctx, userAgg, "123"), + ), + ), + expectFilter(eventFromEventPusher(testSecretGeneratorAddedEvent(domain.SecretGeneratorTypePasswordlessInitCode))), + expectFilterError(io.ErrClosedPipe), + ), + }, + args: args{ + userID: "user1", + resourceOwner: "org1", + authenticator: domain.AuthenticatorAttachmentCrossPlattform, + codeID: "123", + code: code.Plain, + }, + wantErr: io.ErrClosedPipe, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := &Commands{ + eventstore: tt.fields.eventstore, + idGenerator: tt.fields.idGenerator, + webauthnConfig: webauthnConfig, + } + _, err := c.RegisterUserPasskeyWithCode(ctx, tt.args.userID, tt.args.resourceOwner, tt.args.authenticator, tt.args.codeID, tt.args.code, alg) + require.ErrorIs(t, err, tt.wantErr) + // successful case can't be tested due to random challenge. + }) + } +} + +func TestCommands_verifyUserPasskeyCode(t *testing.T) { + ctx := authz.WithRequestedDomain(context.Background(), "example.com") + alg := crypto.CreateMockEncryptionAlg(gomock.NewController(t)) + es := eventstoreExpect(t, + expectFilter(eventFromEventPusher(testSecretGeneratorAddedEvent(domain.SecretGeneratorTypePasswordlessInitCode))), + ) + code, err := newCryptoCodeWithExpiry(ctx, es.Filter, domain.SecretGeneratorTypePasswordlessInitCode, alg) + require.NoError(t, err) + userAgg := &user.NewAggregate("user1", "org1").Aggregate + + type fields struct { + eventstore *eventstore.Eventstore + } + type args struct { + userID string + resourceOwner string + codeID string + code string + } + tests := []struct { + name string + fields fields + args args + want *user.HumanPasswordlessInitCodeCheckSucceededEvent + wantErr error + }{ + { + name: "filter error", + fields: fields{ + eventstore: eventstoreExpect(t, + expectFilterError(io.ErrClosedPipe), + ), + }, + args: args{ + userID: "user1", + resourceOwner: "org1", + codeID: "123", + }, + wantErr: io.ErrClosedPipe, + }, + { + name: "code verification error", + fields: fields{ + eventstore: eventstoreExpect(t, + expectFilter( + eventFromEventPusherWithCreationDateNow( + user.NewHumanPasswordlessInitCodeRequestedEvent(context.Background(), + userAgg, "123", code.Crypted, time.Minute, "", false, + ), + ), + eventFromEventPusherWithCreationDateNow( + user.NewHumanPasswordlessInitCodeSentEvent(ctx, userAgg, "123"), + ), + ), + expectFilter(eventFromEventPusher(testSecretGeneratorAddedEvent(domain.SecretGeneratorTypePasswordlessInitCode))), + expectPush([]*repository.Event{eventFromEventPusher( + user.NewHumanPasswordlessInitCodeCheckFailedEvent(ctx, userAgg, "123"), + )}), + ), + }, + args: args{ + userID: "user1", + resourceOwner: "org1", + codeID: "123", + code: "wrong", + }, + wantErr: caos_errs.ThrowInvalidArgument(err, "COMMAND-Eeb2a", "Errors.User.Code.Invalid"), + }, + { + name: "success", + fields: fields{ + eventstore: eventstoreExpect(t, + expectFilter( + eventFromEventPusherWithCreationDateNow( + user.NewHumanPasswordlessInitCodeRequestedEvent(context.Background(), + userAgg, "123", code.Crypted, time.Minute, "", false, + ), + ), + eventFromEventPusherWithCreationDateNow( + user.NewHumanPasswordlessInitCodeSentEvent(ctx, userAgg, "123"), + ), + ), + expectFilter(eventFromEventPusher(testSecretGeneratorAddedEvent(domain.SecretGeneratorTypePasswordlessInitCode))), + ), + }, + args: args{ + userID: "user1", + resourceOwner: "org1", + codeID: "123", + code: code.Plain, + }, + want: user.NewHumanPasswordlessInitCodeCheckSucceededEvent(ctx, userAgg, "123"), + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := &Commands{ + eventstore: tt.fields.eventstore, + } + got, err := c.verifyUserPasskeyCode(ctx, tt.args.userID, tt.args.resourceOwner, tt.args.codeID, tt.args.code, alg) + require.ErrorIs(t, err, tt.wantErr) + if tt.wantErr == nil { + assert.Equal(t, tt.want, got(ctx, userAgg)) + } + }) + } +} + +func TestCommands_pushUserPasskey(t *testing.T) { + ctx := authz.WithRequestedDomain(context.Background(), "example.com") + webauthnConfig := &webauthn_helper.Config{ + DisplayName: "test", + ExternalSecure: true, + } + userAgg := &user.NewAggregate("user1", "org1").Aggregate + + prep := []expect{ + expectFilter(), // getHumanPasswordlessTokens + expectFilter(eventFromEventPusher( + user.NewHumanAddedEvent(ctx, + userAgg, + "username", + "firstname", + "lastname", + "nickname", + "displayname", + language.German, + domain.GenderUnspecified, + "email@test.ch", + true, + ), + )), + expectFilter(eventFromEventPusher( + org.NewOrgAddedEvent(ctx, + &org.NewAggregate("org1").Aggregate, + "org1", + ), + )), + expectFilter(eventFromEventPusher( + org.NewDomainPolicyAddedEvent(ctx, + &org.NewAggregate("org1").Aggregate, + false, false, false, + ), + )), + expectFilter(eventFromEventPusher( + user.NewHumanWebAuthNAddedEvent(eventstore.NewBaseEventForPush( + ctx, &org.NewAggregate("org1").Aggregate, user.HumanPasswordlessTokenAddedType, + ), "111", "challenge"), + )), + } + + type args struct { + events []eventCallback + } + tests := []struct { + name string + expectPush func(challenge string) expect + args args + wantErr error + }{ + { + name: "push error", + expectPush: func(challenge string) expect { + return expectPushFailed(io.ErrClosedPipe, []*repository.Event{eventFromEventPusher( + user.NewHumanPasswordlessAddedEvent(ctx, + userAgg, "123", challenge, + ), + )}) + }, + args: args{}, + wantErr: io.ErrClosedPipe, + }, + { + name: "success", + expectPush: func(challenge string) expect { + return expectPush([]*repository.Event{eventFromEventPusher( + user.NewHumanPasswordlessAddedEvent(ctx, + userAgg, "123", challenge, + ), + )}) + }, + args: args{}, + }, + { + name: "initcode succeeded event", + expectPush: func(challenge string) expect { + return expectPush([]*repository.Event{ + eventFromEventPusher( + user.NewHumanPasswordlessAddedEvent(ctx, + userAgg, "123", challenge, + ), + ), + eventFromEventPusher( + user.NewHumanPasswordlessInitCodeCheckSucceededEvent(ctx, userAgg, "123"), + ), + }) + }, + args: args{ + events: []eventCallback{func(ctx context.Context, userAgg *eventstore.Aggregate) eventstore.Command { + return user.NewHumanPasswordlessInitCodeCheckSucceededEvent(ctx, userAgg, "123") + }}, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := &Commands{ + eventstore: eventstoreExpect(t, prep...), + webauthnConfig: webauthnConfig, + idGenerator: id_mock.NewIDGeneratorExpectIDs(t, "123"), + } + wm, userAgg, webAuthN, err := c.createUserPasskey(ctx, "user1", "org1", domain.AuthenticatorAttachmentCrossPlattform) + require.NoError(t, err) + + c.eventstore = eventstoreExpect(t, tt.expectPush(webAuthN.Challenge)) + + got, err := c.pushUserPasskey(ctx, wm, userAgg, webAuthN, tt.args.events...) + require.ErrorIs(t, err, tt.wantErr) + if tt.wantErr == nil { + assert.NotEmpty(t, got.PublicKeyCredentialCreationOptions) + assert.Equal(t, "123", got.PasskeyID) + assert.Equal(t, "org1", got.ObjectDetails.ResourceOwner) + } + }) + } +} + +func TestCommands_AddUserPasskeyCode(t *testing.T) { + alg := crypto.CreateMockEncryptionAlg(gomock.NewController(t)) + userAgg := &user.NewAggregate("user1", "org1").Aggregate + type fields struct { + newCode cryptoCodeFunc + eventstore *eventstore.Eventstore + idGenerator id.Generator + } + type args struct { + userID string + resourceOwner string + } + tests := []struct { + name string + fields fields + args args + want *domain.ObjectDetails + wantErr error + }{ + { + name: "id generator error", + fields: fields{ + newCode: newCryptoCodeWithExpiry, + eventstore: eventstoreExpect(t), + idGenerator: id_mock.NewIDGeneratorExpectError(t, io.ErrClosedPipe), + }, + args: args{ + userID: "user1", + resourceOwner: "org1", + }, + wantErr: io.ErrClosedPipe, + }, + { + name: "success", + fields: fields{ + newCode: mockCode("passkey1", time.Minute), + eventstore: eventstoreExpect(t, + expectFilter(eventFromEventPusher( + user.NewHumanAddedEvent(context.Background(), + userAgg, + "username", + "firstname", + "lastname", + "nickname", + "displayname", + language.German, + domain.GenderUnspecified, + "email@test.ch", + true, + ), + )), + expectPush([]*repository.Event{ + eventFromEventPusher( + user.NewHumanPasswordlessInitCodeRequestedEvent(context.Background(), + userAgg, + "123", &crypto.CryptoValue{ + CryptoType: crypto.TypeEncryption, + Algorithm: "enc", + KeyID: "id", + Crypted: []byte("passkey1"), + }, time.Minute, "", false, + ), + ), + }), + ), + idGenerator: id_mock.NewIDGeneratorExpectIDs(t, "123"), + }, + args: args{ + userID: "user1", + resourceOwner: "org1", + }, + want: &domain.ObjectDetails{ + ResourceOwner: "org1", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := &Commands{ + newCode: tt.fields.newCode, + eventstore: tt.fields.eventstore, + idGenerator: tt.fields.idGenerator, + } + got, err := c.AddUserPasskeyCode(context.Background(), tt.args.userID, tt.args.resourceOwner, alg) + require.ErrorIs(t, err, tt.wantErr) + assert.Equal(t, tt.want, got) + }) + } +} + +func TestCommands_AddUserPasskeyCodeURLTemplate(t *testing.T) { + alg := crypto.CreateMockEncryptionAlg(gomock.NewController(t)) + userAgg := &user.NewAggregate("user1", "org1").Aggregate + + type fields struct { + newCode cryptoCodeFunc + eventstore *eventstore.Eventstore + idGenerator id.Generator + } + type args struct { + userID string + resourceOwner string + urlTmpl string + } + tests := []struct { + name string + fields fields + args args + want *domain.ObjectDetails + wantErr error + }{ + { + name: "template error", + fields: fields{ + newCode: newCryptoCodeWithExpiry, + eventstore: eventstoreExpect(t), + }, + args: args{ + userID: "user1", + resourceOwner: "org1", + urlTmpl: "{{", + }, + wantErr: caos_errs.ThrowInvalidArgument(nil, "DOMAIN-oGh5e", "Errors.User.InvalidURLTemplate"), + }, + { + name: "id generator error", + fields: fields{ + newCode: newCryptoCodeWithExpiry, + eventstore: eventstoreExpect(t), + idGenerator: id_mock.NewIDGeneratorExpectError(t, io.ErrClosedPipe), + }, + args: args{ + userID: "user1", + resourceOwner: "org1", + urlTmpl: "https://example.com/passkey/register?userID={{.UserID}}&orgID={{.OrgID}}&codeID={{.CodeID}}&code={{.Code}}", + }, + wantErr: io.ErrClosedPipe, + }, + { + name: "success", + fields: fields{ + newCode: mockCode("passkey1", time.Minute), + eventstore: eventstoreExpect(t, + expectFilter(eventFromEventPusher( + user.NewHumanAddedEvent(context.Background(), + userAgg, + "username", + "firstname", + "lastname", + "nickname", + "displayname", + language.German, + domain.GenderUnspecified, + "email@test.ch", + true, + ), + )), + expectPush([]*repository.Event{ + eventFromEventPusher( + user.NewHumanPasswordlessInitCodeRequestedEvent(context.Background(), + userAgg, + "123", &crypto.CryptoValue{ + CryptoType: crypto.TypeEncryption, + Algorithm: "enc", + KeyID: "id", + Crypted: []byte("passkey1"), + }, + time.Minute, + "https://example.com/passkey/register?userID={{.UserID}}&orgID={{.OrgID}}&codeID={{.CodeID}}&code={{.Code}}", + false, + ), + ), + }), + ), + idGenerator: id_mock.NewIDGeneratorExpectIDs(t, "123"), + }, + args: args{ + userID: "user1", + resourceOwner: "org1", + urlTmpl: "https://example.com/passkey/register?userID={{.UserID}}&orgID={{.OrgID}}&codeID={{.CodeID}}&code={{.Code}}", + }, + want: &domain.ObjectDetails{ + ResourceOwner: "org1", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := &Commands{ + newCode: tt.fields.newCode, + eventstore: tt.fields.eventstore, + idGenerator: tt.fields.idGenerator, + } + got, err := c.AddUserPasskeyCodeURLTemplate(context.Background(), tt.args.userID, tt.args.resourceOwner, alg, tt.args.urlTmpl) + require.ErrorIs(t, err, tt.wantErr) + assert.Equal(t, tt.want, got) + }) + } +} + +func TestCommands_AddUserPasskeyCodeReturn(t *testing.T) { + alg := crypto.CreateMockEncryptionAlg(gomock.NewController(t)) + userAgg := &user.NewAggregate("user1", "org1").Aggregate + type fields struct { + newCode cryptoCodeFunc + eventstore *eventstore.Eventstore + idGenerator id.Generator + } + type args struct { + userID string + resourceOwner string + } + tests := []struct { + name string + fields fields + args args + want *domain.PasskeyCodeDetails + wantErr error + }{ + { + name: "id generator error", + fields: fields{ + newCode: newCryptoCodeWithExpiry, + eventstore: eventstoreExpect(t), + idGenerator: id_mock.NewIDGeneratorExpectError(t, io.ErrClosedPipe), + }, + args: args{ + userID: "user1", + resourceOwner: "org1", + }, + wantErr: io.ErrClosedPipe, + }, + { + name: "success", + fields: fields{ + newCode: mockCode("passkey1", time.Minute), + eventstore: eventstoreExpect(t, + expectFilter(eventFromEventPusher( + user.NewHumanAddedEvent(context.Background(), + userAgg, + "username", + "firstname", + "lastname", + "nickname", + "displayname", + language.German, + domain.GenderUnspecified, + "email@test.ch", + true, + ), + )), + expectPush([]*repository.Event{ + eventFromEventPusher( + user.NewHumanPasswordlessInitCodeRequestedEvent(context.Background(), + userAgg, + "123", &crypto.CryptoValue{ + CryptoType: crypto.TypeEncryption, + Algorithm: "enc", + KeyID: "id", + Crypted: []byte("passkey1"), + }, time.Minute, "", true, + ), + ), + }), + ), + idGenerator: id_mock.NewIDGeneratorExpectIDs(t, "123"), + }, + args: args{ + userID: "user1", + resourceOwner: "org1", + }, + want: &domain.PasskeyCodeDetails{ + ObjectDetails: &domain.ObjectDetails{ + ResourceOwner: "org1", + }, + CodeID: "123", + Code: "passkey1", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := &Commands{ + newCode: tt.fields.newCode, + eventstore: tt.fields.eventstore, + idGenerator: tt.fields.idGenerator, + } + got, err := c.AddUserPasskeyCodeReturn(context.Background(), tt.args.userID, tt.args.resourceOwner, alg) + require.ErrorIs(t, err, tt.wantErr) + assert.Equal(t, tt.want, got) + }) + } +} + +func TestCommands_addUserPasskeyCode(t *testing.T) { + alg := crypto.CreateMockEncryptionAlg(gomock.NewController(t)) + userAgg := &user.NewAggregate("user1", "org1").Aggregate + type fields struct { + newCode cryptoCodeFunc + eventstore *eventstore.Eventstore + idGenerator id.Generator + } + type args struct { + userID string + resourceOwner string + } + tests := []struct { + name string + fields fields + args args + want *domain.PasskeyCodeDetails + wantErr error + }{ + { + name: "id generator error", + fields: fields{ + newCode: newCryptoCodeWithExpiry, + eventstore: eventstoreExpect(t), + idGenerator: id_mock.NewIDGeneratorExpectError(t, io.ErrClosedPipe), + }, + args: args{ + userID: "user1", + resourceOwner: "org1", + }, + wantErr: io.ErrClosedPipe, + }, + { + name: "crypto error", + fields: fields{ + newCode: newCryptoCodeWithExpiry, + eventstore: eventstoreExpect(t, expectFilterError(io.ErrClosedPipe)), + idGenerator: id_mock.NewIDGeneratorExpectIDs(t, "123"), + }, + args: args{ + userID: "user1", + resourceOwner: "org1", + }, + wantErr: io.ErrClosedPipe, + }, + { + name: "filter query error", + fields: fields{ + newCode: newCryptoCodeWithExpiry, + eventstore: eventstoreExpect(t, + expectFilter(eventFromEventPusher(testSecretGeneratorAddedEvent(domain.SecretGeneratorTypePasswordlessInitCode))), + expectFilterError(io.ErrClosedPipe), + ), + idGenerator: id_mock.NewIDGeneratorExpectIDs(t, "123"), + }, + args: args{ + userID: "user1", + resourceOwner: "org1", + }, + wantErr: io.ErrClosedPipe, + }, + { + name: "push error", + fields: fields{ + newCode: mockCode("passkey1", time.Minute), + eventstore: eventstoreExpect(t, + expectFilter(eventFromEventPusher( + user.NewHumanAddedEvent(context.Background(), + userAgg, + "username", + "firstname", + "lastname", + "nickname", + "displayname", + language.German, + domain.GenderUnspecified, + "email@test.ch", + true, + ), + )), + expectPushFailed(io.ErrClosedPipe, []*repository.Event{ + eventFromEventPusher( + user.NewHumanPasswordlessInitCodeRequestedEvent(context.Background(), + &user.NewAggregate("user1", "org1").Aggregate, + "123", &crypto.CryptoValue{ + CryptoType: crypto.TypeEncryption, + Algorithm: "enc", + KeyID: "id", + Crypted: []byte("passkey1"), + }, time.Minute, "", false, + ), + ), + }), + ), + idGenerator: id_mock.NewIDGeneratorExpectIDs(t, "123"), + }, + args: args{ + userID: "user1", + resourceOwner: "org1", + }, + wantErr: io.ErrClosedPipe, + }, + { + name: "success", + fields: fields{ + newCode: mockCode("passkey1", time.Minute), + eventstore: eventstoreExpect(t, + expectFilter(eventFromEventPusher( + user.NewHumanAddedEvent(context.Background(), + userAgg, + "username", + "firstname", + "lastname", + "nickname", + "displayname", + language.German, + domain.GenderUnspecified, + "email@test.ch", + true, + ), + )), + expectPush([]*repository.Event{ + eventFromEventPusher( + user.NewHumanPasswordlessInitCodeRequestedEvent(context.Background(), + userAgg, + "123", &crypto.CryptoValue{ + CryptoType: crypto.TypeEncryption, + Algorithm: "enc", + KeyID: "id", + Crypted: []byte("passkey1"), + }, time.Minute, "", false, + ), + ), + }), + ), + idGenerator: id_mock.NewIDGeneratorExpectIDs(t, "123"), + }, + args: args{ + userID: "user1", + resourceOwner: "org1", + }, + want: &domain.PasskeyCodeDetails{ + ObjectDetails: &domain.ObjectDetails{ + ResourceOwner: "org1", + }, + CodeID: "123", + Code: "passkey1", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := &Commands{ + newCode: tt.fields.newCode, + eventstore: tt.fields.eventstore, + idGenerator: tt.fields.idGenerator, + } + got, err := c.addUserPasskeyCode(context.Background(), tt.args.userID, tt.args.resourceOwner, alg, "", false) + require.ErrorIs(t, err, tt.wantErr) + assert.Equal(t, tt.want, got) + }) + } +} diff --git a/internal/database/postgres/config.go b/internal/database/postgres/config.go index 37ae32cd56..a567f8bc36 100644 --- a/internal/database/postgres/config.go +++ b/internal/database/postgres/config.go @@ -113,14 +113,6 @@ type SSL struct { func (s *Config) checkSSL(user User) { if user.SSL.Mode == sslDisabledMode || user.SSL.Mode == "" { user.SSL = SSL{Mode: sslDisabledMode} - return - } - if user.SSL.RootCert == "" { - logging.WithFields( - "cert set", user.SSL.Cert != "", - "key set", user.SSL.Key != "", - "rootCert set", user.SSL.RootCert != "", - ).Fatal("at least ssl root cert has to be set") } } @@ -149,7 +141,9 @@ func (c Config) String(useAdmin bool) string { fields = append(fields, "dbname=postgres") } if user.SSL.Mode != sslDisabledMode { - fields = append(fields, "sslrootcert="+user.SSL.RootCert) + if user.SSL.RootCert != "" { + fields = append(fields, "sslrootcert="+user.SSL.RootCert) + } if user.SSL.Cert != "" { fields = append(fields, "sslcert="+user.SSL.Cert) } diff --git a/internal/domain/human_email.go b/internal/domain/human_email.go index 578c9fe220..86fd2f9e1c 100644 --- a/internal/domain/human_email.go +++ b/internal/domain/human_email.go @@ -4,12 +4,10 @@ import ( "io" "regexp" "strings" - "text/template" "time" "github.com/zitadel/zitadel/internal/crypto" "github.com/zitadel/zitadel/internal/errors" - caos_errs "github.com/zitadel/zitadel/internal/errors" es_models "github.com/zitadel/zitadel/internal/eventstore/v1/models" ) @@ -73,19 +71,8 @@ type ConfirmURLData struct { OrgID string } -// RenderConfirmURLTemplate parses and renders tmplStr. +// RenderConfirmURLTemplate parses and renders tmpl. // userID, code and orgID are passed into the [ConfirmURLData]. -// "%s%s?userID=%s&code=%s&orgID=%s" -func RenderConfirmURLTemplate(w io.Writer, tmplStr, userID, code, orgID string) error { - tmpl, err := template.New("").Parse(tmplStr) - if err != nil { - return caos_errs.ThrowInvalidArgument(err, "USERv2-ooD8p", "Errors.User.Email.InvalidURLTemplate") - } - - data := &ConfirmURLData{userID, code, orgID} - if err = tmpl.Execute(w, data); err != nil { - return caos_errs.ThrowInvalidArgument(err, "USERv2-ohSi5", "Errors.User.Email.InvalidURLTemplate") - } - - return nil +func RenderConfirmURLTemplate(w io.Writer, tmpl, userID, code, orgID string) error { + return renderURLTemplate(w, tmpl, &ConfirmURLData{userID, code, orgID}) } diff --git a/internal/domain/human_email_test.go b/internal/domain/human_email_test.go index f77ba6d5c2..4b30dd667f 100644 --- a/internal/domain/human_email_test.go +++ b/internal/domain/human_email_test.go @@ -81,10 +81,10 @@ func TestEmailValid(t *testing.T) { func TestRenderConfirmURLTemplate(t *testing.T) { type args struct { - tmplStr string - userID string - code string - orgID string + tmpl string + userID string + code string + orgID string } tests := []struct { name string @@ -95,30 +95,30 @@ func TestRenderConfirmURLTemplate(t *testing.T) { { name: "invalid template", args: args{ - tmplStr: "{{", - userID: "user1", - code: "123", - orgID: "org1", + tmpl: "{{", + userID: "user1", + code: "123", + orgID: "org1", }, - wantErr: caos_errs.ThrowInvalidArgument(nil, "USERv2-ooD8p", "Errors.User.Email.InvalidURLTemplate"), + wantErr: caos_errs.ThrowInvalidArgument(nil, "DOMAIN-oGh5e", "Errors.User.InvalidURLTemplate"), }, { name: "execution error", args: args{ - tmplStr: "{{.Foo}}", - userID: "user1", - code: "123", - orgID: "org1", + tmpl: "{{.Foo}}", + userID: "user1", + code: "123", + orgID: "org1", }, - wantErr: caos_errs.ThrowInvalidArgument(nil, "USERv2-ohSi5", "Errors.User.Email.InvalidURLTemplate"), + wantErr: caos_errs.ThrowInvalidArgument(nil, "DOMAIN-ieYa7", "Errors.User.InvalidURLTemplate"), }, { name: "success", args: args{ - tmplStr: "https://example.com/email/verify?userID={{.UserID}}&code={{.Code}}&orgID={{.OrgID}}", - userID: "user1", - code: "123", - orgID: "org1", + tmpl: "https://example.com/email/verify?userID={{.UserID}}&code={{.Code}}&orgID={{.OrgID}}", + userID: "user1", + code: "123", + orgID: "org1", }, want: "https://example.com/email/verify?userID=user1&code=123&orgID=org1", }, @@ -126,7 +126,7 @@ func TestRenderConfirmURLTemplate(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { var w strings.Builder - err := RenderConfirmURLTemplate(&w, tt.args.tmplStr, tt.args.userID, tt.args.code, tt.args.orgID) + err := RenderConfirmURLTemplate(&w, tt.args.tmpl, tt.args.userID, tt.args.code, tt.args.orgID) require.ErrorIs(t, err, tt.wantErr) assert.Equal(t, tt.want, w.String()) }) diff --git a/internal/domain/idp.go b/internal/domain/idp.go index fc0e8b91fe..f276f8eb4d 100644 --- a/internal/domain/idp.go +++ b/internal/domain/idp.go @@ -91,3 +91,22 @@ func (t IDPType) DisplayName() string { return "" } } + +type IDPIntentState int32 + +const ( + IDPIntentStateUnspecified IDPIntentState = iota + IDPIntentStateStarted + IDPIntentStateSucceeded + IDPIntentStateFailed + + idpIntentStateCount +) + +func (s IDPIntentState) Valid() bool { + return s >= 0 && s < idpIntentStateCount +} + +func (s IDPIntentState) Exists() bool { + return s != IDPIntentStateUnspecified && s != IDPIntentStateFailed //TODO: ? +} diff --git a/internal/domain/url_template.go b/internal/domain/url_template.go new file mode 100644 index 0000000000..172de3496c --- /dev/null +++ b/internal/domain/url_template.go @@ -0,0 +1,19 @@ +package domain + +import ( + "io" + "text/template" + + caos_errs "github.com/zitadel/zitadel/internal/errors" +) + +func renderURLTemplate(w io.Writer, tmpl string, data any) error { + parsed, err := template.New("").Parse(tmpl) + if err != nil { + return caos_errs.ThrowInvalidArgument(err, "DOMAIN-oGh5e", "Errors.User.InvalidURLTemplate") + } + if err = parsed.Execute(w, data); err != nil { + return caos_errs.ThrowInvalidArgument(err, "DOMAIN-ieYa7", "Errors.User.InvalidURLTemplate") + } + return nil +} diff --git a/internal/domain/url_template_test.go b/internal/domain/url_template_test.go new file mode 100644 index 0000000000..1140d14245 --- /dev/null +++ b/internal/domain/url_template_test.go @@ -0,0 +1,56 @@ +package domain + +import ( + "bytes" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + caos_errs "github.com/zitadel/zitadel/internal/errors" +) + +func Test_renderURLTemplate(t *testing.T) { + type args struct { + tmpl string + data any + } + tests := []struct { + name string + args args + wantW string + wantErr error + }{ + { + name: "parse error", + args: args{ + tmpl: "{{", + }, + wantErr: caos_errs.ThrowInvalidArgument(nil, "DOMAIN-oGh5e", "Errors.User.InvalidURLTemplate"), + }, + { + name: "execution error", + args: args{ + tmpl: "{{.Some}}", + data: struct{ Foo int }{Foo: 1}, + }, + wantErr: caos_errs.ThrowInvalidArgument(nil, "DOMAIN-ieYa7", "Errors.User.InvalidURLTemplate"), + }, + { + name: "success", + args: args{ + tmpl: "{{.Foo}}", + data: struct{ Foo int }{Foo: 1}, + }, + wantW: "1", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + w := &bytes.Buffer{} + err := renderURLTemplate(w, tt.args.tmpl, tt.args.data) + require.ErrorIs(t, err, tt.wantErr) + assert.Equal(t, tt.wantW, w.String()) + }) + } +} diff --git a/internal/domain/user_v2_passkey.go b/internal/domain/user_v2_passkey.go new file mode 100644 index 0000000000..37f34097e9 --- /dev/null +++ b/internal/domain/user_v2_passkey.go @@ -0,0 +1,29 @@ +package domain + +import "io" + +type PasskeyURLData struct { + UserID string + OrgID string + CodeID string + Code string +} + +// RenderPasskeyURLTemplate parses and renders tmpl. +// userID, orgID, codeID and code are passed into the [PasskeyURLData]. +func RenderPasskeyURLTemplate(w io.Writer, tmpl, userID, orgID, codeID, code string) error { + return renderURLTemplate(w, tmpl, &PasskeyURLData{userID, orgID, codeID, code}) +} + +type PasskeyCodeDetails struct { + *ObjectDetails + CodeID string + Code string +} + +type PasskeyRegistrationDetails struct { + *ObjectDetails + + PasskeyID string + PublicKeyCredentialCreationOptions []byte +} diff --git a/internal/domain/user_v2_passkey_test.go b/internal/domain/user_v2_passkey_test.go new file mode 100644 index 0000000000..74cb1695e0 --- /dev/null +++ b/internal/domain/user_v2_passkey_test.go @@ -0,0 +1,54 @@ +package domain + +import ( + "bytes" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + caos_errs "github.com/zitadel/zitadel/internal/errors" +) + +func TestRenderPasskeyURLTemplate(t *testing.T) { + type args struct { + tmpl string + userID string + orgID string + codeID string + code string + } + tests := []struct { + name string + args args + wantW string + wantErr error + }{ + { + name: "parse error", + args: args{ + tmpl: "{{", + }, + wantErr: caos_errs.ThrowInvalidArgument(nil, "DOMAIN-oGh5e", "Errors.User.InvalidURLTemplate"), + }, + { + name: "success", + args: args{ + tmpl: "https://example.com/passkey/register?userID={{.UserID}}&orgID={{.OrgID}}&codeID={{.CodeID}}&code={{.Code}}", + userID: "user1", + orgID: "org1", + codeID: "99", + code: "123", + }, + wantW: "https://example.com/passkey/register?userID=user1&orgID=org1&codeID=99&code=123", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + w := &bytes.Buffer{} + err := RenderPasskeyURLTemplate(w, tt.args.tmpl, tt.args.userID, tt.args.orgID, tt.args.codeID, tt.args.code) + require.ErrorIs(t, err, tt.wantErr) + assert.Equal(t, tt.wantW, w.String()) + }) + } +} diff --git a/internal/idp/providers/github/github.go b/internal/idp/providers/github/github.go index bba9a6d9cc..64e02941bc 100644 --- a/internal/idp/providers/github/github.go +++ b/internal/idp/providers/github/github.go @@ -4,11 +4,10 @@ import ( "strconv" "time" - "github.com/zitadel/zitadel/internal/domain" - "golang.org/x/oauth2" "golang.org/x/text/language" + "github.com/zitadel/zitadel/internal/domain" "github.com/zitadel/zitadel/internal/idp" "github.com/zitadel/zitadel/internal/idp/providers/oauth" ) diff --git a/internal/notification/handlers/usernotifier.go b/internal/notification/handlers/usernotifier.go index 10b0952cee..5cd8102361 100644 --- a/internal/notification/handlers/usernotifier.go +++ b/internal/notification/handlers/usernotifier.go @@ -394,6 +394,9 @@ func (u *userNotifier) reducePasswordlessCodeRequested(event eventstore.Event) ( if !ok { return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-EDtjd", "reduce.wrong.event.type %s", user.HumanPasswordlessInitCodeAddedType) } + if e.CodeReturned { + return crdb.NewNoOpStatement(e), nil + } ctx := HandlerContext(event.Aggregate()) alreadyHandled, err := u.checkIfCodeAlreadyHandledOrExpired(ctx, event, e.Expiry, map[string]interface{}{"id": e.ID}, user.HumanPasswordlessInitCodeSentType) if err != nil { @@ -442,7 +445,7 @@ func (u *userNotifier) reducePasswordlessCodeRequested(event eventstore.Event) ( e, u.metricSuccessfulDeliveriesEmail, u.metricFailedDeliveriesEmail, - ).SendPasswordlessRegistrationLink(notifyUser, origin, code, e.ID) + ).SendPasswordlessRegistrationLink(notifyUser, origin, code, e.ID, e.URLTemplate) if err != nil { return nil, err } diff --git a/internal/notification/types/email_verification_code_test.go b/internal/notification/types/email_verification_code_test.go index 0e1975fbc3..71cebaca58 100644 --- a/internal/notification/types/email_verification_code_test.go +++ b/internal/notification/types/email_verification_code_test.go @@ -12,27 +12,6 @@ import ( ) func TestNotify_SendEmailVerificationCode(t *testing.T) { - type res struct { - url string - args map[string]interface{} - messageType string - allowUnverifiedNotificationChannel bool - } - notify := func(dst *res) Notify { - return func( - url string, - args map[string]interface{}, - messageType string, - allowUnverifiedNotificationChannel bool, - ) error { - dst.url = url - dst.args = args - dst.messageType = messageType - dst.allowUnverifiedNotificationChannel = allowUnverifiedNotificationChannel - return nil - } - } - type args struct { user *query.NotifyUser origin string @@ -42,7 +21,7 @@ func TestNotify_SendEmailVerificationCode(t *testing.T) { tests := []struct { name string args args - want *res + want *notifyResult wantErr error }{ { @@ -56,7 +35,7 @@ func TestNotify_SendEmailVerificationCode(t *testing.T) { code: "123", urlTmpl: "", }, - want: &res{ + want: ¬ifyResult{ url: "https://example.com/ui/login/mail/verification?userID=user1&code=123&orgID=org1", args: map[string]interface{}{"Code": "123"}, messageType: domain.VerifyEmailMessageType, @@ -74,8 +53,8 @@ func TestNotify_SendEmailVerificationCode(t *testing.T) { code: "123", urlTmpl: "{{", }, - want: &res{}, - wantErr: caos_errs.ThrowInvalidArgument(nil, "USERv2-ooD8p", "Errors.User.Email.InvalidURLTemplate"), + want: ¬ifyResult{}, + wantErr: caos_errs.ThrowInvalidArgument(nil, "DOMAIN-oGh5e", "Errors.User.InvalidURLTemplate"), }, { name: "template success", @@ -88,7 +67,7 @@ func TestNotify_SendEmailVerificationCode(t *testing.T) { code: "123", urlTmpl: "https://example.com/email/verify?userID={{.UserID}}&code={{.Code}}&orgID={{.OrgID}}", }, - want: &res{ + want: ¬ifyResult{ url: "https://example.com/email/verify?userID=user1&code=123&orgID=org1", args: map[string]interface{}{"Code": "123"}, messageType: domain.VerifyEmailMessageType, @@ -98,8 +77,8 @@ func TestNotify_SendEmailVerificationCode(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got := new(res) - err := notify(got).SendEmailVerificationCode(tt.args.user, tt.args.origin, tt.args.code, tt.args.urlTmpl) + got, notify := mockNotify() + err := notify.SendEmailVerificationCode(tt.args.user, tt.args.origin, tt.args.code, tt.args.urlTmpl) require.ErrorIs(t, err, tt.wantErr) assert.Equal(t, tt.want, got) }) diff --git a/internal/notification/types/passwordless_registration_link.go b/internal/notification/types/passwordless_registration_link.go index 8c6f6894ba..7f4ab00402 100644 --- a/internal/notification/types/passwordless_registration_link.go +++ b/internal/notification/types/passwordless_registration_link.go @@ -1,12 +1,24 @@ package types import ( + "strings" + "github.com/zitadel/zitadel/internal/api/ui/login" "github.com/zitadel/zitadel/internal/domain" "github.com/zitadel/zitadel/internal/query" ) -func (notify Notify) SendPasswordlessRegistrationLink(user *query.NotifyUser, origin, code, codeID string) error { - url := domain.PasswordlessInitCodeLink(origin+login.HandlerPrefix+login.EndpointPasswordlessRegistration, user.ID, user.ResourceOwner, codeID, code) +func (notify Notify) SendPasswordlessRegistrationLink(user *query.NotifyUser, origin, code, codeID, urlTmpl string) error { + var url string + if urlTmpl == "" { + url = domain.PasswordlessInitCodeLink(origin+login.HandlerPrefix+login.EndpointPasswordlessRegistration, user.ID, user.ResourceOwner, codeID, code) + } else { + var buf strings.Builder + if err := domain.RenderPasskeyURLTemplate(&buf, urlTmpl, user.ID, user.ResourceOwner, codeID, code); err != nil { + return err + } + url = buf.String() + } + return notify(url, nil, domain.PasswordlessRegistrationMessageType, true) } diff --git a/internal/notification/types/passwordless_registration_link_test.go b/internal/notification/types/passwordless_registration_link_test.go new file mode 100644 index 0000000000..eb13b94a49 --- /dev/null +++ b/internal/notification/types/passwordless_registration_link_test.go @@ -0,0 +1,88 @@ +package types + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/zitadel/zitadel/internal/domain" + caos_errs "github.com/zitadel/zitadel/internal/errors" + "github.com/zitadel/zitadel/internal/query" +) + +func TestNotify_SendPasswordlessRegistrationLink(t *testing.T) { + type args struct { + user *query.NotifyUser + origin string + code string + codeID string + urlTmpl string + } + tests := []struct { + name string + args args + want *notifyResult + wantErr error + }{ + { + name: "default URL", + args: args{ + user: &query.NotifyUser{ + ID: "user1", + ResourceOwner: "org1", + }, + origin: "https://example.com", + code: "123", + codeID: "456", + urlTmpl: "", + }, + want: ¬ifyResult{ + url: "https://example.com/ui/login/login/passwordless/init?userID=user1&orgID=org1&codeID=456&code=123", + messageType: domain.PasswordlessRegistrationMessageType, + allowUnverifiedNotificationChannel: true, + }, + }, + { + name: "template error", + args: args{ + user: &query.NotifyUser{ + ID: "user1", + ResourceOwner: "org1", + }, + origin: "https://example.com", + code: "123", + codeID: "456", + urlTmpl: "{{", + }, + want: ¬ifyResult{}, + wantErr: caos_errs.ThrowInvalidArgument(nil, "DOMAIN-oGh5e", "Errors.User.InvalidURLTemplate"), + }, + { + name: "template success", + args: args{ + user: &query.NotifyUser{ + ID: "user1", + ResourceOwner: "org1", + }, + origin: "https://example.com", + code: "123", + codeID: "456", + urlTmpl: "https://example.com/passkey/register?userID={{.UserID}}&orgID={{.OrgID}}&codeID={{.CodeID}}&code={{.Code}}", + }, + want: ¬ifyResult{ + url: "https://example.com/passkey/register?userID=user1&orgID=org1&codeID=456&code=123", + messageType: domain.PasswordlessRegistrationMessageType, + allowUnverifiedNotificationChannel: true, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, notify := mockNotify() + err := notify.SendPasswordlessRegistrationLink(tt.args.user, tt.args.origin, tt.args.code, tt.args.codeID, tt.args.urlTmpl) + require.ErrorIs(t, err, tt.wantErr) + assert.Equal(t, tt.want, got) + }) + } +} diff --git a/internal/notification/types/types_test.go b/internal/notification/types/types_test.go new file mode 100644 index 0000000000..1b5066d195 --- /dev/null +++ b/internal/notification/types/types_test.go @@ -0,0 +1,23 @@ +package types + +type notifyResult struct { + url string + args map[string]interface{} + messageType string + allowUnverifiedNotificationChannel bool +} + +// mockNotify returns a notifyResult and Notify function for easy mocking. +// The notifyResult will only be populated after Notify is called. +func mockNotify() (*notifyResult, Notify) { + dst := new(notifyResult) + return dst, func(url string, args map[string]interface{}, messageType string, allowUnverifiedNotificationChannel bool) error { + *dst = notifyResult{ + url: url, + args: args, + messageType: messageType, + allowUnverifiedNotificationChannel: allowUnverifiedNotificationChannel, + } + return nil + } +} diff --git a/internal/query/query.go b/internal/query/query.go index 7e3f10dcdc..17990311b9 100644 --- a/internal/query/query.go +++ b/internal/query/query.go @@ -18,6 +18,7 @@ import ( "github.com/zitadel/zitadel/internal/eventstore" "github.com/zitadel/zitadel/internal/query/projection" "github.com/zitadel/zitadel/internal/repository/action" + "github.com/zitadel/zitadel/internal/repository/idpintent" iam_repo "github.com/zitadel/zitadel/internal/repository/instance" "github.com/zitadel/zitadel/internal/repository/keypair" "github.com/zitadel/zitadel/internal/repository/org" @@ -84,6 +85,7 @@ func StartQueries( keypair.RegisterEventMappers(repo.eventstore) usergrant.RegisterEventMappers(repo.eventstore) session.RegisterEventMappers(repo.eventstore) + idpintent.RegisterEventMappers(repo.eventstore) repo.idpConfigEncryption = idpConfigEncryption repo.multifactors = domain.MultifactorConfigs{ diff --git a/internal/repository/idpintent/aggregate.go b/internal/repository/idpintent/aggregate.go new file mode 100644 index 0000000000..135100b21e --- /dev/null +++ b/internal/repository/idpintent/aggregate.go @@ -0,0 +1,29 @@ +package idpintent + +import ( + "github.com/zitadel/zitadel/internal/eventstore" +) + +const ( + instanceEventTypePrefix = eventstore.EventType("idpintent.") +) + +const ( + AggregateType = "idpintent" + AggregateVersion = "v1" +) + +type Aggregate struct { + eventstore.Aggregate +} + +func NewAggregate(id, resourceOwner string) *Aggregate { + return &Aggregate{ + Aggregate: eventstore.Aggregate{ + Type: AggregateType, + Version: AggregateVersion, + ID: id, + ResourceOwner: resourceOwner, + }, + } +} diff --git a/internal/repository/idpintent/eventstore.go b/internal/repository/idpintent/eventstore.go new file mode 100644 index 0000000000..9e9b4fa155 --- /dev/null +++ b/internal/repository/idpintent/eventstore.go @@ -0,0 +1,11 @@ +package idpintent + +import ( + "github.com/zitadel/zitadel/internal/eventstore" +) + +func RegisterEventMappers(es *eventstore.Eventstore) { + es.RegisterFilterEventMapper(AggregateType, StartedEventType, StartedEventMapper). + RegisterFilterEventMapper(AggregateType, SucceededEventType, SucceededEventMapper). + RegisterFilterEventMapper(AggregateType, FailedEventType, FailedEventMapper) +} diff --git a/internal/repository/idpintent/intent.go b/internal/repository/idpintent/intent.go new file mode 100644 index 0000000000..eea0bf68f5 --- /dev/null +++ b/internal/repository/idpintent/intent.go @@ -0,0 +1,159 @@ +package idpintent + +import ( + "context" + "encoding/json" + "net/url" + + "github.com/zitadel/zitadel/internal/crypto" + "github.com/zitadel/zitadel/internal/errors" + "github.com/zitadel/zitadel/internal/eventstore" + "github.com/zitadel/zitadel/internal/eventstore/repository" +) + +const ( + StartedEventType = instanceEventTypePrefix + "started" + SucceededEventType = instanceEventTypePrefix + "succeeded" + FailedEventType = instanceEventTypePrefix + "failed" +) + +type StartedEvent struct { + eventstore.BaseEvent `json:"-"` + + SuccessURL *url.URL `json:"successURL"` + FailureURL *url.URL `json:"failureURL"` + IDPID string `json:"idpId"` +} + +func NewStartedEvent( + ctx context.Context, + aggregate *eventstore.Aggregate, + successURL, + failureURL *url.URL, + idpID string, +) *StartedEvent { + return &StartedEvent{ + BaseEvent: *eventstore.NewBaseEventForPush( + ctx, + aggregate, + StartedEventType, + ), + SuccessURL: successURL, + FailureURL: failureURL, + IDPID: idpID, + } +} + +func (e *StartedEvent) Data() interface{} { + return e +} + +func (e *StartedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint { + return nil +} + +func StartedEventMapper(event *repository.Event) (eventstore.Event, error) { + e := &StartedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + } + + err := json.Unmarshal(event.Data, e) + if err != nil { + return nil, errors.ThrowInternal(err, "IDP-Sf3f1", "unable to unmarshal event") + } + + return e, nil +} + +type SucceededEvent struct { + eventstore.BaseEvent `json:"-"` + + IDPUser []byte `json:"idpUser"` + UserID string `json:"userId,omitempty"` + IDPAccessToken *crypto.CryptoValue `json:"idpAccessToken,omitempty"` + IDPIDToken string `json:"idpIdToken,omitempty"` +} + +func NewSucceededEvent( + ctx context.Context, + aggregate *eventstore.Aggregate, + idpUser []byte, + userID string, + idpAccessToken *crypto.CryptoValue, + idpIDToken string, +) (*SucceededEvent, error) { + return &SucceededEvent{ + BaseEvent: *eventstore.NewBaseEventForPush( + ctx, + aggregate, + SucceededEventType, + ), + IDPUser: idpUser, + UserID: userID, + IDPAccessToken: idpAccessToken, + IDPIDToken: idpIDToken, + }, nil +} + +func (e *SucceededEvent) Data() interface{} { + return e +} + +func (e *SucceededEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint { + return nil +} + +func SucceededEventMapper(event *repository.Event) (eventstore.Event, error) { + e := &SucceededEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + } + + err := json.Unmarshal(event.Data, e) + if err != nil { + return nil, errors.ThrowInternal(err, "IDP-HBreq", "unable to unmarshal event") + } + + return e, nil +} + +type FailedEvent struct { + eventstore.BaseEvent `json:"-"` + + Reason string `json:"reason,omitempty"` +} + +func NewFailedEvent( + ctx context.Context, + aggregate *eventstore.Aggregate, + reason string, +) *FailedEvent { + return &FailedEvent{ + BaseEvent: *eventstore.NewBaseEventForPush( + ctx, + aggregate, + FailedEventType, + ), + Reason: reason, + } +} + +func (e *FailedEvent) Data() interface{} { + return e +} + +func (e *FailedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint { + return nil +} + +func FailedEventMapper(event *repository.Event) (eventstore.Event, error) { + e := &FailedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + } + + err := json.Unmarshal(event.Data, e) + if err != nil { + return nil, errors.ThrowInternal(err, "IDP-Sfer3", "unable to unmarshal event") + } + + return e, nil +} diff --git a/internal/repository/user/human_mfa_passwordless.go b/internal/repository/user/human_mfa_passwordless.go index 13889277f9..f5e68b6394 100644 --- a/internal/repository/user/human_mfa_passwordless.go +++ b/internal/repository/user/human_mfa_passwordless.go @@ -315,9 +315,11 @@ func HumanPasswordlessInitCodeAddedEventMapper(event *repository.Event) (eventst type HumanPasswordlessInitCodeRequestedEvent struct { eventstore.BaseEvent `json:"-"` - ID string `json:"id"` - Code *crypto.CryptoValue `json:"code"` - Expiry time.Duration `json:"expiry"` + ID string `json:"id"` + Code *crypto.CryptoValue `json:"code"` + Expiry time.Duration `json:"expiry"` + URLTemplate string `json:"url_template,omitempty"` + CodeReturned bool `json:"code_returned,omitempty"` } func (e *HumanPasswordlessInitCodeRequestedEvent) Data() interface{} { @@ -334,6 +336,8 @@ func NewHumanPasswordlessInitCodeRequestedEvent( id string, code *crypto.CryptoValue, expiry time.Duration, + urlTmpl string, + codeReturned bool, ) *HumanPasswordlessInitCodeRequestedEvent { return &HumanPasswordlessInitCodeRequestedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( @@ -341,9 +345,11 @@ func NewHumanPasswordlessInitCodeRequestedEvent( aggregate, HumanPasswordlessInitCodeRequestedType, ), - ID: id, - Code: code, - Expiry: expiry, + ID: id, + Code: code, + Expiry: expiry, + URLTemplate: urlTmpl, + CodeReturned: codeReturned, } } diff --git a/internal/static/i18n/de.yaml b/internal/static/i18n/de.yaml index 9e7e9c5c82..441b6be368 100644 --- a/internal/static/i18n/de.yaml +++ b/internal/static/i18n/de.yaml @@ -53,6 +53,7 @@ Errors: NotFoundOnOrg: Benutzer konnte in der gewünschten Organisation nicht gefunden werden NotAllowedOrg: Benutzer gehört nicht der benötigten Organisation an UserIDMissing: User ID fehlt + UserIDWrong: "Der Anforderungsbenutzer ist nicht gleich dem authentifizierten Benutzer" DomainPolicyNil: Organisation Policy ist leer EmailAsUsernameNotAllowed: Benutzername darf keine E-Mail Adresse sein Invalid: Benutzerdaten sind ungültig @@ -67,6 +68,7 @@ Errors: NoChanges: Keine Änderungen gefunden InitCodeNotFound: Kein Initialisierungs-Code gefunden UsernameNotChanged: Benutzername wurde nicht verändert + InvalidURLTemplate: URL Template ist ungültig Profile: NotFound: Profil nicht gefunden NotChanged: Profil nicht verändert @@ -81,7 +83,6 @@ Errors: NotChanged: Email wurde nicht geändert Empty: Email ist leer IDMissing: Email ID fehlt - InvalidURLTemplate: URL Template ist ungültig Phone: NotFound: Telefonnummer nicht gefunden Invalid: Telefonnummer ist ungültig @@ -475,6 +476,15 @@ Errors: Terminated: Session bereits beendet Token: Invalid: Session Token ist ungültig + Intent: + IDPMissing: IDP ID fehlt im Request + SuccessURLMissing: Success URL fehlt im Request + FailureURLMissing: Failure URL fehlt im Request + StateMissing: State parameter fehlt im Request + NotStarted: Intent wurde nicht gestartet oder wurde bereits beendet + NotSucceeded: Intent war nicht erfolgreich + TokenCreationFailed: Tokenerstellung schlug fehl + InvalidToken: Intent Token ist ungültig AggregateTypes: action: Action diff --git a/internal/static/i18n/en.yaml b/internal/static/i18n/en.yaml index 9362eaf2bd..276ad07da8 100644 --- a/internal/static/i18n/en.yaml +++ b/internal/static/i18n/en.yaml @@ -53,6 +53,7 @@ Errors: NotFoundOnOrg: User could not be found on chosen organization NotAllowedOrg: User is no member of the required organization UserIDMissing: User ID missing + UserIDWrong: "Request user not equal to authenticated user" DomainPolicyNil: Organisation Policy is empty EmailAsUsernameNotAllowed: Email is not allowed as username Invalid: Userdata is invalid @@ -67,6 +68,7 @@ Errors: NoChanges: No changes found InitCodeNotFound: Initialization Code not found UsernameNotChanged: Username not changed + InvalidURLTemplate: URL Template is invalid Profile: NotFound: Profile not found NotChanged: Profile not changed @@ -81,7 +83,6 @@ Errors: NotChanged: Email not changed Empty: Email is empty IDMissing: Email ID is missing - InvalidURLTemplate: URL Template is invalid Phone: NotFound: Phone not found Invalid: Phone is invalid @@ -475,6 +476,15 @@ Errors: Terminated: Session already terminated Token: Invalid: Session Token is invalid + Intent: + IDPMissing: IDP ID is missing in the request + SuccessURLMissing: Success URL is missing in the request + FailureURLMissing: Failure URL is missing in the request + StateMissing: State parameter is missing in the request + NotStarted: Intent is not started or was already terminated + NotSucceeded: Intent has not succeeded + TokenCreationFailed: Token creation failed + InvalidToken: Intent Token is invalid AggregateTypes: action: Action diff --git a/internal/static/i18n/es.yaml b/internal/static/i18n/es.yaml index c87d9f20cd..757a730549 100644 --- a/internal/static/i18n/es.yaml +++ b/internal/static/i18n/es.yaml @@ -53,6 +53,7 @@ Errors: NotFoundOnOrg: El usuario no pudo encontrarse en la organización elegida NotAllowedOrg: El usuario no es miembro de la organización requerida UserIDMissing: Falta el ID de usuario + UserIDWrong: "Solicitud de usuario no igual al usuario autenticado" DomainPolicyNil: Falta la política de la organización EmailAsUsernameNotAllowed: La dirección de Email no se permite como nombre de usuario Invalid: Los datos de usuario no son válidos @@ -67,6 +68,7 @@ Errors: NoChanges: No se encontraron cambios InitCodeNotFound: Código de inicialización no encontrado UsernameNotChanged: El nombre de usuario no cambió + InvalidURLTemplate: La plantilla URL no es válida Profile: NotFound: Perfil no encontrado NotChanged: El perfil no ha cambiado @@ -81,7 +83,6 @@ Errors: NotChanged: El email no ha cambiado Empty: El email no está vacío IDMissing: Falta el ID del email - InvalidURLTemplate: La plantilla URL no es válida Phone: NotFound: Teléfono no encontrado Invalid: El teléfono no es válido @@ -475,6 +476,15 @@ Errors: Terminated: Sesión ya terminada Token: Invalid: El identificador de sesión no es válido + Intent: + IDPMissing: Falta IDP en la solicitud + SuccessURLMissing: Falta la URL de éxito en la solicitud + FailureURLMissing: Falta la URL de error en la solicitud + StateMissing: Falta un parámetro de estado en la solicitud + NotStarted: La intención no se ha iniciado o ya ha finalizado + NotSucceeded: Intento fallido + TokenCreationFailed: Fallo en la creación del token + InvalidToken: El token de la intención no es válido AggregateTypes: action: Acción diff --git a/internal/static/i18n/fr.yaml b/internal/static/i18n/fr.yaml index bc2f111da7..eb5b5471e3 100644 --- a/internal/static/i18n/fr.yaml +++ b/internal/static/i18n/fr.yaml @@ -53,6 +53,7 @@ Errors: NotFoundOnOrg: L'utilisateur n'a pas été trouvé dans l'organisation choisie NotAllowedOrg: L'utilisateur n'est pas membre de l'organisation requise UserIDMissing: L'ID de l'utilisateur est manquant + UserIDWrong: "L'utilisateur de la demande n'est pas égal à l'utilisateur authentifié" DomainPolicyNil: La politique de l'organisation est vide EmailAsUsernameNotAllowed: L'email n'est pas autorisé comme nom d'utilisateur Invalid: Les données de l'utilisateur ne sont pas valides @@ -67,6 +68,7 @@ Errors: NoChanges: Aucun changement trouvé InitCodeNotFound: Code d'initialisation non trouvé UsernameNotChanged: Nom d'utilisateur non modifié + InvalidURLTemplate: Le modèle d'URL n'est pas valide Profile: NotFound: Profil non trouvé NotChanged: Le profil n'a pas changé @@ -81,7 +83,6 @@ Errors: NotChanged: L'adresse électronique n'a pas changé Empty: Email est vide IDMissing: Email ID manquant - InvalidURLTemplate: Le modèle d'URL n'est pas valide Phone: Notfound: Téléphone non trouvé Invalid: Le téléphone n'est pas valide @@ -475,6 +476,15 @@ Errors: Terminated: La session est déjà terminée Token: Invalid: Le jeton de session n'est pas valide + Intent: + IDPMissing: IDP manquant dans la requête + SuccessURLMissing: Success URL absent de la requête + FailureURLMissing: Failure URL absent de la requête + StateMissing: Paramètre d'état manquant dans la requête + NotStarted: Intent n'a pas démarré ou s'est déjà terminé + NotSucceeded: l'intention n'a pas abouti + TokenCreationFailed: La création du token a échoué + InvalidToken: Le jeton d'intention n'est pas valide AggregateTypes: action: Action diff --git a/internal/static/i18n/it.yaml b/internal/static/i18n/it.yaml index f270a5f690..7ce4200b76 100644 --- a/internal/static/i18n/it.yaml +++ b/internal/static/i18n/it.yaml @@ -53,6 +53,7 @@ Errors: NotFoundOnOrg: L'utente non è stato trovato nell'organizzazione scelta NotAllowedOrg: L'utente non è membro dell'organizzazione richiesta UserIDMissing: ID utente mancante + UserIDWrong: "Utente richiesta non uguale all'utente autenticato" DomainPolicyNil: Impostazione Org IAM mancante EmailAsUsernameNotAllowed: L'e-mail non è consentita come nome utente Invalid: I dati utente non sono validi @@ -67,6 +68,7 @@ Errors: NoChanges: Nessun cambiamento trovato InitCodeNotFound: Codice di inizializzazione non trovato UsernameNotChanged: Nome utente non cambiato + InvalidURLTemplate: Il modello di URL non è valido Profile: NotFound: Profilo non trovato NotChanged: Profilo non cambiato @@ -81,7 +83,6 @@ Errors: NotChanged: Email non cambiata Empty: Email è vuota IDMissing: Email ID mancante - InvalidURLTemplate: Il modello di URL non è valido Phone: NotFound: Telefono non trovato Invalid: Il telefono non è valido @@ -475,6 +476,15 @@ Errors: Terminated: Sessione già terminata Token: Invalid: Il token della sessione non è valido + Intent: + IDPMissing: IDP mancante nella richiesta + SuccessURLMissing: URL di successo mancante nella richiesta + FailureURLMissing: URL di errore mancante nella richiesta + StateMissing: parametro di stato mancante nella richiesta + NotStarted: l'intento non è stato avviato o è già stato terminato + NotSucceeded: l'intento non è andato a buon fine + TokenCreationFailed: creazione del token fallita + InvalidToken: Il token dell'intento non è valido AggregateTypes: action: Azione diff --git a/internal/static/i18n/ja.yaml b/internal/static/i18n/ja.yaml index 284c0412a8..394880e116 100644 --- a/internal/static/i18n/ja.yaml +++ b/internal/static/i18n/ja.yaml @@ -53,6 +53,7 @@ Errors: NotFoundOnOrg: ユーザーが選択した組織内で見つかりません NotAllowedOrg: ユーザーが必要な組織のメンバーでありません UserIDMissing: ユーザーIDがありません + UserIDWrong: "リクエストユーザーが認証されたユーザーと等しくない" DomainPolicyNil: 組織ポリシーが空です EmailAsUsernameNotAllowed: メールアドレスはユーザー名として使用できません Invalid: 無効なユーザーデータです @@ -67,6 +68,7 @@ Errors: NoChanges: 変更は見つかりません InitCodeNotFound: 初期化コードが見つかりません UsernameNotChanged: ユーザー名は変更されていません + InvalidURLTemplate: URLテンプレートが無効です Profile: NotFound: プロファイルが見つかりません NotChanged: プロファイルが変更されていません @@ -76,7 +78,6 @@ Errors: Invalid: 無効なメールアドレスです AlreadyVerified: メールアドレスはすでに検証済みです NotChanged: メールアドレスが変更されていません - InvalidURLTemplate: URLテンプレートが無効です Phone: NotFound: 電話番号が見つかりません Invalid: 無効な電話番号です @@ -464,6 +465,15 @@ Errors: Terminated: セッションはすでに終了しています Token: Invalid: セッショントークンが無効です + Intent: + IDPMissing: リクエストにIDP IDが含まれていません + SuccessURLMissing: リクエストに成功時の URL がありません + FailureURLMissing: リクエストに失敗の URL がありません + StateMissing: リクエストに State パラメータがありません + NotStarted: インテントが開始されなかったか、既に終了している + NotSucceeded: インテントが成功しなかった + TokenCreationFailed: トークンの作成に失敗しました + InvalidToken: インテントのトークンが無効である AggregateTypes: action: アクション diff --git a/internal/static/i18n/pl.yaml b/internal/static/i18n/pl.yaml index 9fac79a257..3be75368b9 100644 --- a/internal/static/i18n/pl.yaml +++ b/internal/static/i18n/pl.yaml @@ -53,6 +53,7 @@ Errors: NotFoundOnOrg: Użytkownik nie został znaleziony w wybranej organizacji NotAllowedOrg: Użytkownik nie jest członkiem wymaganej organizacji UserIDMissing: Brakuje ID użytkownika + UserIDWrong: "Żądanie użytkownika nie jest równe uwierzytelnionemu użytkownikowi" DomainPolicyNil: Polityka organizacji jest pusta EmailAsUsernameNotAllowed: Adres e-mail nie jest dozwolony jako nazwa użytkownika Invalid: Dane użytkownika są nieprawidłowe @@ -67,6 +68,7 @@ Errors: NoChanges: Nie znaleziono zmian InitCodeNotFound: Kod inicjalizacji nie znaleziony UsernameNotChanged: Nazwa użytkownika nie została zmieniona + InvalidURLTemplate: Szablon URL jest nieprawidłowy Profile: NotFound: Profil nie znaleziony NotChanged: Profil nie zmieniony @@ -81,7 +83,6 @@ Errors: NotChanged: Adres e-mail nie zmieniony Empty: Adres e-mail jest pusty IDMissing: Adres e-mail ID brakuje - InvalidURLTemplate: Szablon URL jest nieprawidłowy Phone: NotFound: Numer telefonu nie znaleziony Invalid: Numer telefonu jest nieprawidłowy @@ -475,6 +476,15 @@ Errors: Terminated: Sesja już zakończona Token: Invalid: Token sesji jest nieprawidłowy + Intent: + IDPMissing: Brak identyfikatora IDP w żądaniu + SuccessURLMissing: Brak adresu URL powodzenia w żądaniu + FailureURLMissing: Brak adresu URL niepowodzenia w żądaniu + StateMissing: Brak parametru stanu w żądaniu + NotStarted: Intencja nie została rozpoczęta lub już się zakończyła + NotSucceeded: intencja nie powiodła się + TokenCreationFailed: Tworzenie tokena nie powiodło się + InvalidToken: Token intencji jest nieprawidłowy AggregateTypes: action: Działanie diff --git a/internal/static/i18n/zh.yaml b/internal/static/i18n/zh.yaml index c36cbcd111..eb3a76c77f 100644 --- a/internal/static/i18n/zh.yaml +++ b/internal/static/i18n/zh.yaml @@ -53,6 +53,7 @@ Errors: NotFoundOnOrg: 在所选组织中找不到用户 NotAllowedOrg: 用户不是所需组织的成员 UserIDMissing: 缺少用户 ID + UserIDWrong: "请求用户不等于经过身份验证的用户" DomainPolicyNil: 组织策略为空 EmailAsUsernameNotAllowed: 电子邮件不允许作为用户名 Invalid: 用户数据无效 @@ -67,6 +68,7 @@ Errors: NoChanges: 未发现任何更改 InitCodeNotFound: 未找到初始化验证码 UsernameNotChanged: 用户名未更改 + InvalidURLTemplate: URL模板无效 Profile: NotFound: 未找到个人资料 NotChanged: 个人资料未更改 @@ -81,7 +83,6 @@ Errors: NotChanged: 电子邮件未更改 Empty: 电子邮件是空的 IDMissing: 电子邮件ID丢失 - InvalidURLTemplate: URL模板无效 Phone: NotFound: 手机号码未找到 Invalid: 手机号码无效 @@ -475,6 +476,15 @@ Errors: Terminated: 会话已经终止 Token: Invalid: 会话令牌是无效的 + Intent: + IDPMissing: 请求中缺少IDP ID + SuccessURLMissing: 请求中缺少成功URL + FailureURLMissing: 请求中缺少失败的URL + StateMissing: 请求中缺少状态参数 + NotStarted: 意图没有开始或已经结束 + NotSucceeded: 意图不成功 + TokenCreationFailed: 令牌创建失败 + InvalidToken: 意图令牌是无效的 AggregateTypes: action: 动作 diff --git a/internal/webauthn/client.go b/internal/webauthn/client.go new file mode 100644 index 0000000000..ac7fbe766a --- /dev/null +++ b/internal/webauthn/client.go @@ -0,0 +1,36 @@ +package webauthn + +import ( + "fmt" + + "github.com/descope/virtualwebauthn" +) + +type Client struct { + rp virtualwebauthn.RelyingParty + auth virtualwebauthn.Authenticator + credential virtualwebauthn.Credential +} + +func NewClient(name, domain, origin string) *Client { + rp := virtualwebauthn.RelyingParty{ + Name: name, + ID: domain, + Origin: origin, + } + return &Client{ + rp: rp, + auth: virtualwebauthn.NewAuthenticator(), + credential: virtualwebauthn.NewCredential(virtualwebauthn.KeyTypeEC2), + } +} + +func (c *Client) CreateAttestationResponse(options []byte) ([]byte, error) { + parsedAttestationOptions, err := virtualwebauthn.ParseAttestationOptions(string(options)) + if err != nil { + return nil, fmt.Errorf("webauthn.Client.CreateAttestationResponse: %w", err) + } + return []byte(virtualwebauthn.CreateAttestationResponse( + c.rp, c.auth, c.credential, *parsedAttestationOptions, + )), nil +} diff --git a/internal/webauthn/converter.go b/internal/webauthn/converter.go index 431980c829..9b49ec0163 100644 --- a/internal/webauthn/converter.go +++ b/internal/webauthn/converter.go @@ -1,8 +1,9 @@ package webauthn import ( - "github.com/duo-labs/webauthn/protocol" - "github.com/duo-labs/webauthn/webauthn" + "github.com/go-webauthn/webauthn/protocol" + "github.com/go-webauthn/webauthn/webauthn" + "github.com/zitadel/zitadel/internal/domain" ) diff --git a/internal/webauthn/webauthn.go b/internal/webauthn/webauthn.go index d1a62819b0..5d2517bc47 100644 --- a/internal/webauthn/webauthn.go +++ b/internal/webauthn/webauthn.go @@ -5,8 +5,8 @@ import ( "context" "encoding/json" - "github.com/duo-labs/webauthn/protocol" - "github.com/duo-labs/webauthn/webauthn" + "github.com/go-webauthn/webauthn/protocol" + "github.com/go-webauthn/webauthn/webauthn" "github.com/zitadel/logging" "github.com/zitadel/zitadel/internal/api/authz" @@ -177,9 +177,13 @@ func (w *Config) FinishLogin(ctx context.Context, user *domain.Human, webAuthN * func (w *Config) serverFromContext(ctx context.Context) (*webauthn.WebAuthn, error) { instance := authz.GetInstance(ctx) - return webauthn.New(&webauthn.Config{ + webAuthn, err := webauthn.New(&webauthn.Config{ RPDisplayName: w.DisplayName, RPID: instance.RequestedDomain(), - RPOrigin: http.BuildOrigin(instance.RequestedHost(), w.ExternalSecure), + RPOrigins: []string{http.BuildOrigin(instance.RequestedHost(), w.ExternalSecure)}, }) + if err != nil { + return nil, caos_errs.ThrowInternal(err, "WEBAU-UX9ta", "Errors.User.WebAuthN.ServerConfig") + } + return webAuthn, nil } diff --git a/internal/webauthn/webauthn_test.go b/internal/webauthn/webauthn_test.go new file mode 100644 index 0000000000..df05d34e92 --- /dev/null +++ b/internal/webauthn/webauthn_test.go @@ -0,0 +1,58 @@ +package webauthn + +import ( + "context" + "testing" + + "github.com/go-webauthn/webauthn/webauthn" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/zitadel/zitadel/internal/api/authz" + caos_errs "github.com/zitadel/zitadel/internal/errors" +) + +func TestConfig_serverFromContext(t *testing.T) { + type args struct { + ctx context.Context + } + tests := []struct { + name string + args args + want *webauthn.WebAuthn + wantErr error + }{ + { + name: "webauthn error", + args: args{context.Background()}, + wantErr: caos_errs.ThrowInternal(nil, "WEBAU-UX9ta", "Errors.User.WebAuthN.ServerConfig"), + }, + { + name: "success", + args: args{authz.WithRequestedDomain(context.Background(), "example.com")}, + want: &webauthn.WebAuthn{ + Config: &webauthn.Config{ + RPDisplayName: "DisplayName", + RPID: "example.com", + RPOrigins: []string{"https://example.com"}, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + w := &Config{ + DisplayName: "DisplayName", + ExternalSecure: true, + } + got, err := w.serverFromContext(tt.args.ctx) + require.ErrorIs(t, err, tt.wantErr) + if tt.want != nil { + require.NotNil(t, got) + assert.Equal(t, tt.want.Config.RPDisplayName, got.Config.RPDisplayName) + assert.Equal(t, tt.want.Config.RPID, got.Config.RPID) + assert.Equal(t, tt.want.Config.RPOrigins, got.Config.RPOrigins) + } + }) + } +} diff --git a/proto/zitadel/system.proto b/proto/zitadel/system.proto index b34977e621..4bfec35e6e 100644 --- a/proto/zitadel/system.proto +++ b/proto/zitadel/system.proto @@ -229,7 +229,7 @@ service SystemService { }; } - // Returns the domain of an instance + // Removes the domain of an instance rpc RemoveDomain(RemoveDomainRequest) returns (RemoveDomainResponse) { option (google.api.http) = { delete: "/instances/{instance_id}/domains/{domain}"; @@ -240,7 +240,7 @@ service SystemService { }; } - // Returns the domain of an instance + // Sets the primary domain of an instance rpc SetPrimaryDomain(SetPrimaryDomainRequest) returns (SetPrimaryDomainResponse) { option (google.api.http) = { post: "/instances/{instance_id}/domains/_set_primary"; diff --git a/proto/zitadel/user/v2alpha/auth.proto b/proto/zitadel/user/v2alpha/auth.proto new file mode 100644 index 0000000000..92ac47b5f4 --- /dev/null +++ b/proto/zitadel/user/v2alpha/auth.proto @@ -0,0 +1,50 @@ +syntax = "proto3"; + +package zitadel.user.v2alpha; + +option go_package = "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha;user"; + +import "google/api/field_behavior.proto"; +import "protoc-gen-openapiv2/options/annotations.proto"; +import "validate/validate.proto"; + +enum PasskeyAuthenticator { + PASSKEY_AUTHENTICATOR_UNSPECIFIED = 0; + PASSKEY_AUTHENTICATOR_PLATFORM = 1; + PASSKEY_AUTHENTICATOR_CROSS_PLATFORM = 2; +} + +message SendPasskeyRegistrationLink { + optional string url_template = 1 [ + (validate.rules).string = {min_len: 1, max_len: 200}, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + min_length: 1; + max_length: 200; + example: "\"https://example.com/passkey/register?userID={{.UserID}}&orgID={{.OrgID}}&codeID={{.CodeID}}&code={{.Code}}\""; + description: "\"Optionally set a url_template, which will be used in the mail sent by ZITADEL to guide the user to your passkey registration page. If no template is set, the default ZITADEL url will be used.\"" + } + ]; +} + +message ReturnPasskeyRegistrationCode {} + +message PasskeyRegistrationCode { + string id = 1 [ + (validate.rules).string = {min_len: 1, max_len: 200}, + (google.api.field_behavior) = REQUIRED, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "\"id to the one time code generated by ZITADEL\""; + example: "\"e2a48d6a-362b-4db6-a1fb-34feab84dc62\""; + max_length: 200; + } + ]; + string code = 2 [ + (validate.rules).string = {min_len: 1, max_len: 200}, + (google.api.field_behavior) = REQUIRED, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "\"one time code generated by ZITADEL\""; + example: "\"SomeSpecialCode\""; + max_length: 200; + } + ]; +} diff --git a/proto/zitadel/user/v2alpha/email.proto b/proto/zitadel/user/v2alpha/email.proto index 151348b55a..3022ffc2a6 100644 --- a/proto/zitadel/user/v2alpha/email.proto +++ b/proto/zitadel/user/v2alpha/email.proto @@ -30,7 +30,6 @@ message SetHumanEmail { message SendEmailVerificationCode { optional string url_template = 1 [ (validate.rules).string = {min_len: 1, max_len: 200}, - (google.api.field_behavior) = REQUIRED, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { min_length: 1; max_length: 200; diff --git a/proto/zitadel/user/v2alpha/idp.proto b/proto/zitadel/user/v2alpha/idp.proto new file mode 100644 index 0000000000..ed8f389c36 --- /dev/null +++ b/proto/zitadel/user/v2alpha/idp.proto @@ -0,0 +1,51 @@ +syntax = "proto3"; + +package zitadel.user.v2alpha; + +option go_package = "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha;user"; + +import "google/api/field_behavior.proto"; +import "protoc-gen-openapiv2/options/annotations.proto"; +import "validate/validate.proto"; + +message IDPInformation{ + oneof access{ + IDPOAuthAccessInformation oauth = 1; + } + bytes idp_information = 2; +} + +message IDPOAuthAccessInformation{ + string access_token = 1; + optional string id_token = 2; +} + +message IDPLink { + string idp_id = 1 [ + (validate.rules).string = {min_len: 1, max_len: 200}, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "ID of the identity provider" + min_length: 1; + max_length: 200; + example: "\"d654e6ba-70a3-48ef-a95d-37c8d8a7901a\""; + } + ]; + string idp_external_id = 2 [ + (validate.rules).string = {min_len: 1, max_len: 200}, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "ID of user of the identity provider" + min_length: 1; + max_length: 200; + example: "\"d654e6ba-70a3-48ef-a95d-37c8d8a7901a\""; + } + ]; + string display_name = 3 [ + (validate.rules).string = {min_len: 1, max_len: 200}, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "Display name of user of the identity provider" + min_length: 1; + max_length: 200; + example: "\"Firstname Lastname\""; + } + ]; +} diff --git a/proto/zitadel/user/v2alpha/user_service.proto b/proto/zitadel/user/v2alpha/user_service.proto index f899d91f7a..1af446f09a 100644 --- a/proto/zitadel/user/v2alpha/user_service.proto +++ b/proto/zitadel/user/v2alpha/user_service.proto @@ -4,11 +4,14 @@ package zitadel.user.v2alpha; import "zitadel/object/v2alpha/object.proto"; import "zitadel/protoc_gen_zitadel/v2/options.proto"; +import "zitadel/user/v2alpha/auth.proto"; import "zitadel/user/v2alpha/email.proto"; +import "zitadel/user/v2alpha/idp.proto"; import "zitadel/user/v2alpha/password.proto"; import "zitadel/user/v2alpha/user.proto"; import "google/api/annotations.proto"; import "google/api/field_behavior.proto"; +import "google/protobuf/duration.proto"; import "protoc-gen-openapiv2/options/annotations.proto"; import "validate/validate.proto"; @@ -153,6 +156,147 @@ service UserService { }; }; } + + rpc RegisterPasskey (RegisterPasskeyRequest) returns (RegisterPasskeyResponse) { + option (google.api.http) = { + post: "/v2alpha/users/{user_id}/passkeys" + body: "*" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "authenticated" + } + }; + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + summary: "Start the registration of passkey for a user"; + description: "Start the registration of a passkey for a user, as a response the public key credential creation options are returned, which are used to verify the passkey." + responses: { + key: "200" + value: { + description: "OK"; + } + }; + }; + } + rpc VerifyPasskeyRegistration (VerifyPasskeyRegistrationRequest) returns (VerifyPasskeyRegistrationResponse) { + option (google.api.http) = { + post: "/v2alpha/users/{user_id}/passkeys/{passkey_id}" + body: "*" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "authenticated" + } + }; + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + summary: "Verify a passkey for a user"; + description: "Verify the passkey registration with the public key credential." + responses: { + key: "200" + value: { + description: "OK"; + } + }; + }; + } + rpc CreatePasskeyRegistrationLink (CreatePasskeyRegistrationLinkRequest) returns (CreatePasskeyRegistrationLinkResponse) { + option (google.api.http) = { + post: "/v2alpha/users/{user_id}/passkeys/registration_link" + body: "*" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "user.passkey.write" + } + }; + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + summary: "Create a passkey registration link for a user"; + description: "Create a passkey registration link which includes a code and either return it or send it to the user." + responses: { + key: "200" + value: { + description: "OK"; + } + }; + }; + } + + // Start an IDP authentication (for external login, registration or linking) + rpc StartIdentityProviderFlow (StartIdentityProviderFlowRequest) returns (StartIdentityProviderFlowResponse) { + option (google.api.http) = { + post: "/v2alpha/users/idps/{idp_id}/start" + body: "*" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "authenticated" + } + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + summary: "Start flow with an identity provider"; + description: "Start a flow with an identity provider, for external login, registration or linking"; + responses: { + key: "200" + value: { + description: "OK"; + } + }; + }; + } + + rpc RetrieveIdentityProviderInformation (RetrieveIdentityProviderInformationRequest) returns (RetrieveIdentityProviderInformationResponse) { + option (google.api.http) = { + post: "/v2alpha/users/intents/{intent_id}/information" + body: "*" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "authenticated" + } + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + summary: "Retrieve the information returned by the identity provider"; + description: "Retrieve the information returned by the identity provider for registration or updating an existing user with new information"; + responses: { + key: "200" + value: { + description: "OK"; + } + }; + }; + } + + // Link an IDP to an existing user + rpc AddIDPLink (AddIDPLinkRequest) returns (AddIDPLinkResponse) { + option (google.api.http) = { + post: "/v2alpha/users/users/{user_id}/links" + body: "*" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "authenticated" + } + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + summary: "Add link to an identity provider to an user"; + description: "Add link to an identity provider to an user"; + responses: { + key: "200" + value: { + description: "OK"; + } + }; + }; + } } message AddHumanUserRequest{ @@ -188,6 +332,7 @@ message AddHumanUserRequest{ Password password = 7; HashedPassword hashed_password = 8; } + repeated IDPLink idp_links = 9; } message AddHumanUserResponse { @@ -254,3 +399,195 @@ message VerifyEmailRequest{ message VerifyEmailResponse{ zitadel.object.v2alpha.Details details = 1; } + +message RegisterPasskeyRequest{ + string user_id = 1 [ + (validate.rules).string = {min_len: 1, max_len: 200}, + (google.api.field_behavior) = REQUIRED, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + min_length: 1; + max_length: 200; + example: "\"d654e6ba-70a3-48ef-a95d-37c8d8a7901a\""; + } + ]; + optional PasskeyRegistrationCode code = 2 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "\"one time code generated by ZITADEL; required to start the passkey registration without user authentication\""; + } + ]; + PasskeyAuthenticator authenticator = 3 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "\"Optionally specify the authenticator type of the passkey device (platform or cross-platform). If none is provided, both values are allowed.\""; + } + ]; +} + +message RegisterPasskeyResponse{ + zitadel.object.v2alpha.Details details = 1; + string passkey_id = 2 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"fabde5c8-c13f-481d-a90b-5e59a001a076\"" + } + ]; + bytes public_key_credential_creation_options = 3 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "json representation of public key credential creation options used by the passkey client" + example: "\"eyJwdWJsaWNLZXkiOnsiY2hhbGxlbmdlIoplfZm4vM21qSzBPdjltN2x6VWhnclYyejFJSlVzZnpLd0Z1TytWTWtzRW1Icz0iLCJycCI6eyJuYW1lIjoiWklUQURFTCIsImlkIjoiYWNtZS1nem9lNHgueml0YWRlbC5jbG91ZCJ9LCJ1c2VyIjp7Im5hbWUiOiJ0ZXN0dXNlcjU1QGFjbWUueml0YWRlbC5jbG91ZCIsImRpc3BsYXlOYW1lIjoiVGVzdCBUZXN0IiwiaWQiOiJNVGd5TVRVMk1qWTBNakk1TXpBMk5qSTEifSwicHViS2V5Q3JlZFBhcmFtcyI6W3sidHlwZSI6InB1YmxpYy1rZXkiLCJhbGciOi03fSx7InR5cGUiOiJwdWJsaWMta2V5IiwiYWxnIjotMzV9LHsidHlwZSI6InB1YmxpYy1rZXkiLCJhbGciOi0zNn0seyJ0eXBlIjoicHVibGljLWtleSIsImFsZyI6LTI1N30seyJ0eXBlIjoicHVibGljLWtleSIsImFsZyI6LTI1OH0seyJ0eXBlIjoicHVibGljLWtleSIsImFsZyI6LTI1OX0seyJ0eXBlIjoicHVibGljLWtleSIsImFsZyI6LTM3fSx7InR5cGUiOiJwdWJsaWMta2V5IiwiYWxnIjotMzh9LHsidHlwZSI6InB1YmxpYy1rZXkiLCJhbGciOi0zOX0seyJ0eXBlIjoicHVibGljLWtleSIsImFsZyI6LTh9XSwiYXV0aGVudGljYXRvclNlbGVjdGlvbiI6eyJ1c2VyVmVyaWZpY2F0aW9uIjoiZGlzY291cmFnZWQifn2ilGltZW91dCI6NjAwMDAsImF0dGVzdGF0aW9uIjoibm9uZSJ9fQ==\"" + } + ]; +} + +message VerifyPasskeyRegistrationRequest{ + string user_id = 1 [ + (validate.rules).string = {min_len: 1, max_len: 200}, + (google.api.field_behavior) = REQUIRED, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + min_length: 1; + max_length: 200; + example: "\"d654e6ba-70a3-48ef-a95d-37c8d8a7901a\""; + } + ]; + string passkey_id = 2 [ + (validate.rules).string = {min_len: 1, max_len: 200}, + (google.api.field_behavior) = REQUIRED, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + min_length: 1; + max_length: 200; + example: "\"fabde5c8-c13f-481d-a90b-5e59a001a076\""; + } + ]; + bytes public_key_credential = 3 [ + (validate.rules).bytes = {min_len: 55, max_len: 1048576}, + (google.api.field_behavior) = REQUIRED, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "JSON representation of public key credential issued by the passkey client"; + min_length: 55; + max_length: 1048576; //1 MB + } + ]; + string passkey_name = 4 [ + (validate.rules).string = {min_len: 1, max_len: 200}, + (google.api.field_behavior) = REQUIRED, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + min_length: 1; + max_length: 200; + example: "\"fido key\"" + } + ]; +} + +message VerifyPasskeyRegistrationResponse{ + zitadel.object.v2alpha.Details details = 1; +} + +message CreatePasskeyRegistrationLinkRequest{ + string user_id = 1 [ + (validate.rules).string = {min_len: 1, max_len: 200}, + (google.api.field_behavior) = REQUIRED, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + min_length: 1; + max_length: 200; + example: "\"d654e6ba-70a3-48ef-a95d-37c8d8a7901a\""; + } + ]; + // if no medium is specified, an email is sent with the default url + oneof medium { + SendPasskeyRegistrationLink send_link = 2; + ReturnPasskeyRegistrationCode return_code = 3; + } +} + +message CreatePasskeyRegistrationLinkResponse{ + zitadel.object.v2alpha.Details details = 1; + // in case the medium was set to return_code, the code will be returned + optional PasskeyRegistrationCode code = 2 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "\"one time code generated by ZITADEL; required to start the passkey registration without user authentication\""; + } + ]; +} + +message StartIdentityProviderFlowRequest{ + string idp_id = 1 [ + (validate.rules).string = {min_len: 1, max_len: 200}, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "ID for existing identity provider" + min_length: 1; + max_length: 200; + example: "\"d654e6ba-70a3-48ef-a95d-37c8d8a7901a\""; + } + ]; + string success_url = 2 [ + (validate.rules).string = {min_len: 1, max_len: 200, uri_ref: true}, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "URL on which the user will be redirected after a successful login" + min_length: 1; + max_length: 200; + example: "\"https://custom.com/login/idp/success\""; + } + ]; + string failure_url = 3 [ + (validate.rules).string = {min_len: 1, max_len: 200, uri_ref: true}, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "URL on which the user will be redirected after a failed login" + min_length: 1; + max_length: 200; + example: "\"https://custom.com/login/idp/fail\""; + } + ]; +} + +message StartIdentityProviderFlowResponse{ + zitadel.object.v2alpha.Details details = 1; + oneof next_step { + string auth_url = 2 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "URL to which the client should redirect" + example: "\"https://accounts.google.com/o/oauth2/v2/auth?client_id=clientID&callback=https%3A%2F%2Fzitadel.cloud%2Fidps%2Fcallback\""; + } + ]; + } +} + +message RetrieveIdentityProviderInformationRequest{ + string intent_id = 1 [ + (validate.rules).string = {min_len: 1, max_len: 200}, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "ID of the intent, previously returned on the success response of the IDP callback" + min_length: 1; + max_length: 200; + example: "\"d654e6ba-70a3-48ef-a95d-37c8d8a7901a\""; + } + ]; + string token = 2 [ + (validate.rules).string = {min_len: 1, max_len: 200}, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "token of the intent, previously returned on the success response of the IDP callback" + min_length: 1; + max_length: 200; + example: "\"SJKL3ioIDpo342ioqw98fjp3sdf32wahb=\""; + } + ]; +} + +message RetrieveIdentityProviderInformationResponse{ + zitadel.object.v2alpha.Details details = 1; + IDPInformation idp_information = 2; +} + +message AddIDPLinkRequest{ + string user_id = 1 [ + (validate.rules).string = {min_len: 1, max_len: 200}, + (google.api.field_behavior) = REQUIRED, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + min_length: 1; + max_length: 200; + example: "\"69629026806489455\""; + } + ]; + IDPLink idp_link = 2; +} + +message AddIDPLinkResponse { + zitadel.object.v2alpha.Details details = 1; +}