diff --git a/cmd/setup/11.go b/cmd/setup/11.go index 77d42bb88..917f479e0 100644 --- a/cmd/setup/11.go +++ b/cmd/setup/11.go @@ -53,23 +53,21 @@ func (mig *AddEventCreatedAt) Execute(ctx context.Context) error { } for i := 0; ; i++ { - var count int64 - err := crdb.ExecuteTx(ctx, mig.dbClient.DB, nil, func(tx *sql.Tx) error { + var affected int64 + err = crdb.ExecuteTx(ctx, mig.dbClient.DB, nil, func(tx *sql.Tx) error { res, err := tx.Exec(setCreatedAt, mig.BulkAmount) if err != nil { return err } - count, _ = res.RowsAffected() - logging.WithFields("affected", count).Info("created_at updated") - + affected, _ = res.RowsAffected() return nil }) if err != nil { return err } - logging.WithFields("step", "11", "iteration", i, "count", count).Info("set created_at iteration done") - if count < int64(mig.BulkAmount) { + logging.WithFields("step", "11", "iteration", i, "affected", affected).Info("set created_at iteration done") + if affected < int64(mig.BulkAmount) { break } } diff --git a/cmd/start/start.go b/cmd/start/start.go index 75516fba4..e91b628d9 100644 --- a/cmd/start/start.go +++ b/cmd/start/start.go @@ -47,6 +47,7 @@ import ( auth_es "github.com/zitadel/zitadel/internal/auth/repository/eventsourcing" "github.com/zitadel/zitadel/internal/authz" authz_repo "github.com/zitadel/zitadel/internal/authz/repository" + authz_es "github.com/zitadel/zitadel/internal/authz/repository/eventsourcing/eventstore" "github.com/zitadel/zitadel/internal/command" "github.com/zitadel/zitadel/internal/crypto" cryptoDB "github.com/zitadel/zitadel/internal/crypto/database" @@ -145,6 +146,11 @@ func startZitadel(config *Config, masterKey string, server chan<- *Server) error keys.SAML, config.InternalAuthZ.RolePermissionMappings, sessionTokenVerifier, + func(q *query.Queries) domain.PermissionCheck { + return func(ctx context.Context, permission, orgID, resourceID string) (err error) { + return internal_authz.CheckPermission(ctx, &authz_es.UserMembershipRepo{Queries: q}, config.InternalAuthZ.RolePermissionMappings, permission, orgID, resourceID) + } + }, ) if err != nil { return fmt.Errorf("cannot start queries: %w", err) diff --git a/console/package-lock.json b/console/package-lock.json index acdadd6fd..e4f541e63 100644 --- a/console/package-lock.json +++ b/console/package-lock.json @@ -8,18 +8,18 @@ "name": "console", "version": "0.0.0", "dependencies": { - "@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", + "@angular/animations": "^16.1.2", + "@angular/cdk": "^16.1.2", + "@angular/common": "^16.1.2", + "@angular/compiler": "^16.1.2", + "@angular/core": "^16.1.2", + "@angular/forms": "^16.1.2", + "@angular/material": "^16.1.2", + "@angular/material-moment-adapter": "^16.1.2", + "@angular/platform-browser": "^16.1.2", + "@angular/platform-browser-dynamic": "^16.1.2", + "@angular/router": "^16.1.2", + "@angular/service-worker": "^16.1.2", "@ctrl/ngx-codemirror": "^6.1.0", "@grpc/grpc-js": "^1.8.14", "@ngx-translate/core": "^14.0.0", @@ -37,7 +37,8 @@ "libphonenumber-js": "^1.10.30", "material-design-icons-iconfont": "^6.1.1", "moment": "^2.29.4", - "ngx-color": "^8.0.3", + "opentype.js": "^1.3.4", + "ngx-color": "^9.0.0", "rxjs": "~7.8.0", "tinycolor2": "^1.6.0", "tslib": "^2.4.1", @@ -45,25 +46,26 @@ "zone.js": "~0.13.0" }, "devDependencies": { - "@angular-devkit/build-angular": "^16.0.1", + "@angular-devkit/build-angular": "^16.1.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", + "@angular/cli": "^16.1.1", + "@angular/compiler-cli": "^16.1.2", + "@angular/language-service": "^16.1.2", "@bufbuild/buf": "^1.18.0-1", "@types/file-saver": "^2.0.2", "@types/google-protobuf": "^3.15.3", - "@types/jasmine": "~4.3.0", + "@types/jasmine": "~4.3.3", "@types/jasminewd2": "~2.0.10", "@types/jsonwebtoken": "^9.0.1", "@types/node": "^18.15.11", + "@types/opentype.js": "^1.3.4", "@types/qrcode": "^1.5.0", "@types/uuid": "^9.0.1", - "@typescript-eslint/eslint-plugin": "^5.59.2", + "@typescript-eslint/eslint-plugin": "^5.59.11", "@typescript-eslint/parser": "^5.59.5", "codelyzer": "^6.0.2", "eslint": "^8.39.0", @@ -94,12 +96,12 @@ } }, "node_modules/@angular-devkit/architect": { - "version": "0.1600.1", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1600.1.tgz", - "integrity": "sha512-7N3Dugrp3Fyyn3Q6RsxFNJJ2m1QuqcF3GHJcX7siINL37Hp6xI/q5gKffcd9rf20H1DYZE0VIbR1Sk31G6hMWg==", + "version": "0.1601.1", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1601.1.tgz", + "integrity": "sha512-LUHaxdAZrvh++7/R+/hzVY5moEVVTjd30b25SNNYcNJsWox1Yh9idu1AvtEuZR/A8Jj+sbHnuw0176GsJ78stg==", "dev": true, "dependencies": { - "@angular-devkit/core": "16.0.1", + "@angular-devkit/core": "16.1.1", "rxjs": "7.8.1" }, "engines": { @@ -109,40 +111,40 @@ } }, "node_modules/@angular-devkit/build-angular": { - "version": "16.0.1", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-16.0.1.tgz", - "integrity": "sha512-VFhUViBfONOf6Ji4Lfkxlk+GN5l8Owm4Z0McqUIegrXsq3aSSStBBFdaDESpzhS6GIGqEBjjHMUQK8IlWT+EIQ==", + "version": "16.1.1", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-16.1.1.tgz", + "integrity": "sha512-k+9hQLGgGWHj7NJ7Fm6nwCDsvseKlipKE6Me9ydliNKclwJ0l+ScpXS/iZA1+Geud7IX3McGWf2QemWj1Nds9g==", "dev": true, "dependencies": { "@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", + "@angular-devkit/architect": "0.1601.1", + "@angular-devkit/build-webpack": "0.1601.1", + "@angular-devkit/core": "16.1.1", + "@babel/core": "7.22.5", + "@babel/generator": "7.22.5", + "@babel/helper-annotate-as-pure": "7.22.5", + "@babel/helper-split-export-declaration": "7.22.5", "@babel/plugin-proposal-async-generator-functions": "7.20.7", - "@babel/plugin-transform-async-to-generator": "7.20.7", - "@babel/plugin-transform-runtime": "7.21.4", - "@babel/preset-env": "7.21.4", - "@babel/runtime": "7.21.0", - "@babel/template": "7.20.7", + "@babel/plugin-transform-async-to-generator": "7.22.5", + "@babel/plugin-transform-runtime": "7.22.5", + "@babel/preset-env": "7.22.5", + "@babel/runtime": "7.22.5", + "@babel/template": "7.22.5", "@discoveryjs/json-ext": "0.5.7", - "@ngtools/webpack": "16.0.1", + "@ngtools/webpack": "16.1.1", "@vitejs/plugin-basic-ssl": "1.0.1", "ansi-colors": "4.1.3", "autoprefixer": "10.4.14", "babel-loader": "9.1.2", "babel-plugin-istanbul": "6.1.1", - "browserslist": "4.21.5", - "cacache": "17.0.6", + "browserslist": "^4.21.5", + "cacache": "17.1.3", "chokidar": "3.5.3", "copy-webpack-plugin": "11.0.0", - "critters": "0.0.16", - "css-loader": "6.7.3", - "esbuild-wasm": "0.17.18", - "glob": "8.1.0", + "critters": "0.0.19", + "css-loader": "6.8.1", + "esbuild-wasm": "0.17.19", + "fast-glob": "3.2.12", "https-proxy-agent": "5.0.1", "inquirer": "8.2.4", "jsonc-parser": "3.2.0", @@ -152,31 +154,31 @@ "license-webpack-plugin": "4.0.2", "loader-utils": "3.2.1", "magic-string": "0.30.0", - "mini-css-extract-plugin": "2.7.5", + "mini-css-extract-plugin": "2.7.6", "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.23", - "postcss-loader": "7.2.4", + "postcss": "8.4.24", + "postcss-loader": "7.3.2", "resolve-url-loader": "5.0.0", "rxjs": "7.8.1", - "sass": "1.62.1", - "sass-loader": "13.2.2", - "semver": "7.4.0", + "sass": "1.63.2", + "sass-loader": "13.3.1", + "semver": "7.5.1", "source-map-loader": "4.0.1", "source-map-support": "0.5.21", - "terser": "5.17.1", + "terser": "5.17.7", "text-table": "0.2.0", "tree-kill": "1.2.2", - "tslib": "2.5.0", - "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", + "tslib": "2.5.3", + "vite": "4.3.9", + "webpack": "5.86.0", + "webpack-dev-middleware": "6.1.1", + "webpack-dev-server": "4.15.0", + "webpack-merge": "5.9.0", "webpack-subresource-integrity": "5.1.0" }, "engines": { @@ -185,20 +187,20 @@ "yarn": ">= 1.13.0" }, "optionalDependencies": { - "esbuild": "0.17.18" + "esbuild": "0.17.19" }, "peerDependencies": { - "@angular/compiler-cli": "^16.0.0", - "@angular/localize": "^16.0.0", - "@angular/platform-server": "^16.0.0", - "@angular/service-worker": "^16.0.0", + "@angular/compiler-cli": "^16.1.0", + "@angular/localize": "^16.1.0", + "@angular/platform-server": "^16.1.0", + "@angular/service-worker": "^16.1.0", "jest": "^29.5.0", "jest-environment-jsdom": "^29.5.0", "karma": "^6.3.0", - "ng-packagr": "^16.0.0", + "ng-packagr": "^16.1.0", "protractor": "^7.0.0", "tailwindcss": "^2.0.0 || ^3.0.0", - "typescript": ">=4.9.3 <5.1" + "typescript": ">=4.9.3 <5.2" }, "peerDependenciesMeta": { "@angular/localize": { @@ -230,13 +232,85 @@ } } }, - "node_modules/@angular-devkit/build-webpack": { - "version": "0.1600.1", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1600.1.tgz", - "integrity": "sha512-yCy5A1UwGzpst3QJ/CRo2Y8HWRqTPOfwAPAVl91Lbch7gBFViRvq6E7N1XfQunPu/eXvKxbuq2mFSDqtyZ1mWw==", + "node_modules/@angular-devkit/build-angular/node_modules/@babel/core": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.5.tgz", + "integrity": "sha512-SBuTAjg91A3eKOvD+bPEz3LlhHZRNu1nFOVts9lzDJTXshHTjII0BAtDS3Y2DAkdZdDKWVZGVwkDfc4Clxn1dg==", "dev": true, "dependencies": { - "@angular-devkit/architect": "0.1600.1", + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.22.5", + "@babel/generator": "^7.22.5", + "@babel/helper-compilation-targets": "^7.22.5", + "@babel/helper-module-transforms": "^7.22.5", + "@babel/helpers": "^7.22.5", + "@babel/parser": "^7.22.5", + "@babel/template": "^7.22.5", + "@babel/traverse": "^7.22.5", + "@babel/types": "^7.22.5", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.2", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@babel/core/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/@angular-devkit/build-angular/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/@angular-devkit/build-angular/node_modules/semver": { + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz", + "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@angular-devkit/build-angular/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/@angular-devkit/build-webpack": { + "version": "0.1601.1", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1601.1.tgz", + "integrity": "sha512-J1O+5qiwCYNCFTKtczhWC3wycuks/3GitmbYv3GMSBz2HJU5XSTtGdlkSvkwCocLHa8ggPlnquLsQNjwcd+EQg==", + "dev": true, + "dependencies": { + "@angular-devkit/architect": "0.1601.1", "rxjs": "7.8.1" }, "engines": { @@ -250,9 +324,9 @@ } }, "node_modules/@angular-devkit/core": { - "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==", + "version": "16.1.1", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-16.1.1.tgz", + "integrity": "sha512-rhyY/N4iKbpfKmErmNmAfBLMrc1H8u8NlfcU6lwN6kbBbM8BfvLk9b7g4JXOfiOQfp4BnQ8CFf7xcIUy4++Tog==", "dev": true, "dependencies": { "ajv": "8.12.0", @@ -276,12 +350,12 @@ } }, "node_modules/@angular-devkit/schematics": { - "version": "16.0.1", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-16.0.1.tgz", - "integrity": "sha512-A9D0LTYmiqiBa90GKcSuWb7hUouGIbm/AHbJbjL85WLLRbQA2PwKl7P5Mpd6nS/ZC0kfG4VQY3VOaDvb3qpI9g==", + "version": "16.1.1", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-16.1.1.tgz", + "integrity": "sha512-s8LFr0m4ILEpJuQj78fCWKocnRleA3MWJU1Q5LZloCcUB8fdDvaPNCt5s0VWC2Sp+4OCxJaSN3kjjcFbCYFvTA==", "dev": true, "dependencies": { - "@angular-devkit/core": "16.0.1", + "@angular-devkit/core": "16.1.1", "jsonc-parser": "3.2.0", "magic-string": "0.30.0", "ora": "5.4.1", @@ -392,9 +466,9 @@ } }, "node_modules/@angular/animations": { - "version": "16.0.1", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-16.0.1.tgz", - "integrity": "sha512-ziRq1hGJJuQqQUHqNpEMp9uy1pVutvL8oNvawblh32u4bnLsVQU5gMd6sTonn0x4sphEwMNnuEmp/q6QRIx+pA==", + "version": "16.1.2", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-16.1.2.tgz", + "integrity": "sha512-Q2hdXYKaNGCRQf1G2E1L/P0lw5thAkC0g/L2GdmB+bgyPCTTk1B7WxDN/SVUCfdz1nReZiLepL3Y24RKeQ6Blw==", "dependencies": { "tslib": "^2.3.0" }, @@ -402,13 +476,13 @@ "node": "^16.14.0 || >=18.10.0" }, "peerDependencies": { - "@angular/core": "16.0.1" + "@angular/core": "16.1.2" } }, "node_modules/@angular/cdk": { - "version": "16.0.1", - "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-16.0.1.tgz", - "integrity": "sha512-GupYss6x84RWEoy3JTYu4Igr2SxHuV6whVKMScQG2/Gm+winOsOn7YWm0IZQuFnjSWIF2Va5B0Tp0IjFHWxTvA==", + "version": "16.1.2", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-16.1.2.tgz", + "integrity": "sha512-sUiaY6QgiplSuhzN7Fp5HUW3HPyz3g8ET45W0I2bSiSmSaDEATLWwVXfxSC4/ZL+YdZHoC9LkYKDSktPO2EDaA==", "dependencies": { "tslib": "^2.3.0" }, @@ -422,27 +496,27 @@ } }, "node_modules/@angular/cli": { - "version": "16.0.1", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-16.0.1.tgz", - "integrity": "sha512-0vIAcq/S+3NXXN4/gBQFVGaxLUQ0zhRxxHQQuiT7GGII73UySuhwvaFB1BEhYG5HVJjRrP1F0ZYbvsvrmFzfXQ==", + "version": "16.1.1", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-16.1.1.tgz", + "integrity": "sha512-QrTgMqMnamteZu2x3JhLMo6wBjI05zMr9RQfMHWq4UrUpTqBcHAMqJIKSSbvrtuRbolLrQyLorwxzlmEOfEmbQ==", "dev": true, "dependencies": { - "@angular-devkit/architect": "0.1600.1", - "@angular-devkit/core": "16.0.1", - "@angular-devkit/schematics": "16.0.1", - "@schematics/angular": "16.0.1", + "@angular-devkit/architect": "0.1601.1", + "@angular-devkit/core": "16.1.1", + "@angular-devkit/schematics": "16.1.1", + "@schematics/angular": "16.1.1", "@yarnpkg/lockfile": "1.1.0", "ansi-colors": "4.1.3", - "ini": "4.0.0", + "ini": "4.1.1", "inquirer": "8.2.4", "jsonc-parser": "3.2.0", "npm-package-arg": "10.1.0", "npm-pick-manifest": "8.0.1", "open": "8.4.2", "ora": "5.4.1", - "pacote": "15.1.3", + "pacote": "15.2.0", "resolve": "1.22.2", - "semver": "7.4.0", + "semver": "7.5.1", "symbol-observable": "4.0.0", "yargs": "17.7.2" }, @@ -455,10 +529,43 @@ "yarn": ">= 1.13.0" } }, + "node_modules/@angular/cli/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/@angular/cli/node_modules/semver": { + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz", + "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@angular/cli/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/@angular/common": { - "version": "16.0.1", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-16.0.1.tgz", - "integrity": "sha512-ic9Ri4Mepf4c0BTff7o4Oyl/a1vACNXXUzuoTwIjWnIqrH89dtwg7ncTD9Rv0N1lon7r4gXokTbn9A/Yk/0jbw==", + "version": "16.1.2", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-16.1.2.tgz", + "integrity": "sha512-MrJ1CUKg4H8fH0Jc771gLceVcawBPjIM6TSLEM7DMeX7SZ6eSU9HAOCTHXBg7Kmb7ZS19G1BQBD/tkjivszk+Q==", "dependencies": { "tslib": "^2.3.0" }, @@ -466,14 +573,14 @@ "node": "^16.14.0 || >=18.10.0" }, "peerDependencies": { - "@angular/core": "16.0.1", + "@angular/core": "16.1.2", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/compiler": { - "version": "16.0.1", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-16.0.1.tgz", - "integrity": "sha512-7zNo6H1qVQow3T4EUul76SaIDSMRSl0hmtyWUzPjtWkxMjrCPSduqjA4/NHaG0KX1BsUvUtQEoDJ5jv/7EHWTQ==", + "version": "16.1.2", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-16.1.2.tgz", + "integrity": "sha512-uLUyesolGL8sEb03GfwSFbtTa++XPQyabAUi53Nz5jzRhFzxCa6cO7w4DCxp7yzQM+8jiPKAuw9bQDNv1eYR7A==", "dependencies": { "tslib": "^2.3.0" }, @@ -481,7 +588,7 @@ "node": "^16.14.0 || >=18.10.0" }, "peerDependencies": { - "@angular/core": "16.0.1" + "@angular/core": "16.1.2" }, "peerDependenciesMeta": { "@angular/core": { @@ -490,12 +597,12 @@ } }, "node_modules/@angular/compiler-cli": { - "version": "16.0.1", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-16.0.1.tgz", - "integrity": "sha512-EW7Oxp8EuTz3vCNd4RAncZGB7dCUYviUkBA4PzuyPmL2copZPt12j9qx0pXXF3T6ydjoZ+99ZEgfkKOV6FeU3g==", + "version": "16.1.2", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-16.1.2.tgz", + "integrity": "sha512-7Z4qPNv6zRTF8U0CEAqJMF2kzyImilOgGwp92PqwhycZIj/MQyN7Txv8uv2rghhCr9jt9bL2vrHPJNGD2UNLxw==", "dev": true, "dependencies": { - "@babel/core": "7.19.3", + "@babel/core": "7.21.8", "@jridgewell/sourcemap-codec": "^1.4.14", "chokidar": "^3.0.0", "convert-source-map": "^1.5.1", @@ -513,53 +620,14 @@ "node": "^16.14.0 || >=18.10.0" }, "peerDependencies": { - "@angular/compiler": "16.0.1", - "typescript": ">=4.9.3 <5.1" - } - }, - "node_modules/@angular/compiler-cli/node_modules/@babel/core": { - "version": "7.19.3", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.3.tgz", - "integrity": "sha512-WneDJxdsjEvyKtXKsaBGbDeiyOjR5vYq4HcShxnIbG0qixpoHjI3MqeZM9NDvsojNCEBItQE4juOo/bU6e72gQ==", - "dev": true, - "dependencies": { - "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.19.3", - "@babel/helper-compilation-targets": "^7.19.3", - "@babel/helper-module-transforms": "^7.19.0", - "@babel/helpers": "^7.19.0", - "@babel/parser": "^7.19.3", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.3", - "@babel/types": "^7.19.3", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.1", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@angular/compiler-cli/node_modules/@babel/core/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" + "@angular/compiler": "16.1.2", + "typescript": ">=4.9.3 <5.2" } }, "node_modules/@angular/core": { - "version": "16.0.1", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-16.0.1.tgz", - "integrity": "sha512-3s4XBbzWgyWcjI0WFlNDKRxsbm4J+OKIL4mJCM9r8gWwno9y0K/giziAm9YMIJ4VOBIvrcMbOh85o44FCk8cRA==", + "version": "16.1.2", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-16.1.2.tgz", + "integrity": "sha512-1w8DcSY/ZJT6qBaZWZGNQ50YQ5Cffm7xXSIcjIZeQwQKRAZNlZ1O/pFEer1kvxkAbVsQH3Nf6kB6t8PkNFCWMg==", "dependencies": { "tslib": "^2.3.0" }, @@ -572,9 +640,9 @@ } }, "node_modules/@angular/forms": { - "version": "16.0.1", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-16.0.1.tgz", - "integrity": "sha512-VbH/YnEBau0q97zI7BjSk0pu/i2S0Y/zmhvA2wgI2CCvtbqT6hCNdE/3rW6ZFBcnuCe+dFhuchXe6dX28epsvg==", + "version": "16.1.2", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-16.1.2.tgz", + "integrity": "sha512-OyAQRYE6B2NbucoE5KzmxkQqFFlcSnB8/LWS/J9KHGB1QkPdYJCuWSccypeo4YxgVjYCSvHDnO6jBiHDfwDBuQ==", "dependencies": { "tslib": "^2.3.0" }, @@ -582,78 +650,78 @@ "node": "^16.14.0 || >=18.10.0" }, "peerDependencies": { - "@angular/common": "16.0.1", - "@angular/core": "16.0.1", - "@angular/platform-browser": "16.0.1", + "@angular/common": "16.1.2", + "@angular/core": "16.1.2", + "@angular/platform-browser": "16.1.2", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/language-service": { - "version": "16.0.1", - "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-16.0.1.tgz", - "integrity": "sha512-m5+B0vi92le8EIxrlOruijNSjYG2Nny8hrAwt4yhoMr9HIym9nGeMXgYKYurMnqigI7zq/ZwJfnpmZ7QwjYkgA==", + "version": "16.1.2", + "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-16.1.2.tgz", + "integrity": "sha512-pCneNUjrr7SYUBeqqznoGA5V+RTRMljrg4WFufth3jtnKRCWE1XR+MYNDGejfOx/mQZNxBsjz4l83FTwiqjsRQ==", "dev": true, "engines": { "node": "^16.14.0 || >=18.10.0" } }, "node_modules/@angular/material": { - "version": "16.0.1", - "resolved": "https://registry.npmjs.org/@angular/material/-/material-16.0.1.tgz", - "integrity": "sha512-J7qI60CXgixSLtepxzKzSkid9pxgruUfQDfZeTXSzg7WFb7/OgFeggUx0p/BlbC2NIdTaIFBBh71GNve/c1O9Q==", + "version": "16.1.2", + "resolved": "https://registry.npmjs.org/@angular/material/-/material-16.1.2.tgz", + "integrity": "sha512-lG88yMnlRkPqXxWpT4Uh3YxwQY3xzaV8dP/Rr3Qtlh0yhp2CEWBmC6Cu1VcHpq0G3VLapO61PIzxSj9125CN5Q==", "dependencies": { - "@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", + "@material/animation": "15.0.0-canary.90291f2e2.0", + "@material/auto-init": "15.0.0-canary.90291f2e2.0", + "@material/banner": "15.0.0-canary.90291f2e2.0", + "@material/base": "15.0.0-canary.90291f2e2.0", + "@material/button": "15.0.0-canary.90291f2e2.0", + "@material/card": "15.0.0-canary.90291f2e2.0", + "@material/checkbox": "15.0.0-canary.90291f2e2.0", + "@material/chips": "15.0.0-canary.90291f2e2.0", + "@material/circular-progress": "15.0.0-canary.90291f2e2.0", + "@material/data-table": "15.0.0-canary.90291f2e2.0", + "@material/density": "15.0.0-canary.90291f2e2.0", + "@material/dialog": "15.0.0-canary.90291f2e2.0", + "@material/dom": "15.0.0-canary.90291f2e2.0", + "@material/drawer": "15.0.0-canary.90291f2e2.0", + "@material/elevation": "15.0.0-canary.90291f2e2.0", + "@material/fab": "15.0.0-canary.90291f2e2.0", + "@material/feature-targeting": "15.0.0-canary.90291f2e2.0", + "@material/floating-label": "15.0.0-canary.90291f2e2.0", + "@material/form-field": "15.0.0-canary.90291f2e2.0", + "@material/icon-button": "15.0.0-canary.90291f2e2.0", + "@material/image-list": "15.0.0-canary.90291f2e2.0", + "@material/layout-grid": "15.0.0-canary.90291f2e2.0", + "@material/line-ripple": "15.0.0-canary.90291f2e2.0", + "@material/linear-progress": "15.0.0-canary.90291f2e2.0", + "@material/list": "15.0.0-canary.90291f2e2.0", + "@material/menu": "15.0.0-canary.90291f2e2.0", + "@material/menu-surface": "15.0.0-canary.90291f2e2.0", + "@material/notched-outline": "15.0.0-canary.90291f2e2.0", + "@material/radio": "15.0.0-canary.90291f2e2.0", + "@material/ripple": "15.0.0-canary.90291f2e2.0", + "@material/rtl": "15.0.0-canary.90291f2e2.0", + "@material/segmented-button": "15.0.0-canary.90291f2e2.0", + "@material/select": "15.0.0-canary.90291f2e2.0", + "@material/shape": "15.0.0-canary.90291f2e2.0", + "@material/slider": "15.0.0-canary.90291f2e2.0", + "@material/snackbar": "15.0.0-canary.90291f2e2.0", + "@material/switch": "15.0.0-canary.90291f2e2.0", + "@material/tab": "15.0.0-canary.90291f2e2.0", + "@material/tab-bar": "15.0.0-canary.90291f2e2.0", + "@material/tab-indicator": "15.0.0-canary.90291f2e2.0", + "@material/tab-scroller": "15.0.0-canary.90291f2e2.0", + "@material/textfield": "15.0.0-canary.90291f2e2.0", + "@material/theme": "15.0.0-canary.90291f2e2.0", + "@material/tooltip": "15.0.0-canary.90291f2e2.0", + "@material/top-app-bar": "15.0.0-canary.90291f2e2.0", + "@material/touch-target": "15.0.0-canary.90291f2e2.0", + "@material/typography": "15.0.0-canary.90291f2e2.0", "tslib": "^2.3.0" }, "peerDependencies": { "@angular/animations": "^16.0.0 || ^17.0.0", - "@angular/cdk": "16.0.1", + "@angular/cdk": "16.1.2", "@angular/common": "^16.0.0 || ^17.0.0", "@angular/core": "^16.0.0 || ^17.0.0", "@angular/forms": "^16.0.0 || ^17.0.0", @@ -662,22 +730,22 @@ } }, "node_modules/@angular/material-moment-adapter": { - "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==", + "version": "16.1.2", + "resolved": "https://registry.npmjs.org/@angular/material-moment-adapter/-/material-moment-adapter-16.1.2.tgz", + "integrity": "sha512-6M0Zu1U0InhNpOScDEtI0rm8FK5JojiliTKj73AOy1LWusOeE6fGzE7Y6qHk3tBJWxQH7Z+SRy7c3cqRzlhLqQ==", "dependencies": { "tslib": "^2.3.0" }, "peerDependencies": { "@angular/core": "^16.0.0 || ^17.0.0", - "@angular/material": "16.0.1", + "@angular/material": "16.1.2", "moment": "^2.18.1" } }, "node_modules/@angular/platform-browser": { - "version": "16.0.1", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-16.0.1.tgz", - "integrity": "sha512-7XLIOnTnGDJLE4Q0zBz6eI9q5V3NnsTAJqIICJHc4gk6jNgVz90gtejAQ4EFbo0d83XGzwFL22hxID5Dj1WRIA==", + "version": "16.1.2", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-16.1.2.tgz", + "integrity": "sha512-jFelRYaVaD2F2ph+Z4tsQUxpw1gGiOU0t5i77srrHDtm+KXpERyYbnXQTog+6q+ScNtsB++0JNkiPQV6oOjtIw==", "dependencies": { "tslib": "^2.3.0" }, @@ -685,9 +753,9 @@ "node": "^16.14.0 || >=18.10.0" }, "peerDependencies": { - "@angular/animations": "16.0.1", - "@angular/common": "16.0.1", - "@angular/core": "16.0.1" + "@angular/animations": "16.1.2", + "@angular/common": "16.1.2", + "@angular/core": "16.1.2" }, "peerDependenciesMeta": { "@angular/animations": { @@ -696,9 +764,9 @@ } }, "node_modules/@angular/platform-browser-dynamic": { - "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==", + "version": "16.1.2", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-16.1.2.tgz", + "integrity": "sha512-gBPvQ2tAGSUK8oCnL15rCzO9/gyzYR8pf6a7kQdDA1Vr3Aj02UCsJOZvedoMxbnGpLtw3JGWMqZ+bvp4/tCw1g==", "dependencies": { "tslib": "^2.3.0" }, @@ -706,16 +774,16 @@ "node": "^16.14.0 || >=18.10.0" }, "peerDependencies": { - "@angular/common": "16.0.1", - "@angular/compiler": "16.0.1", - "@angular/core": "16.0.1", - "@angular/platform-browser": "16.0.1" + "@angular/common": "16.1.2", + "@angular/compiler": "16.1.2", + "@angular/core": "16.1.2", + "@angular/platform-browser": "16.1.2" } }, "node_modules/@angular/router": { - "version": "16.0.1", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-16.0.1.tgz", - "integrity": "sha512-4GH0SxPbuY08B/M0f3NEHf9yIFH+D3wlzWJHI75chfdqQ8gGAMG6B6PSmo3haicDxHcSnZTYNJXDLOQvaBAHcA==", + "version": "16.1.2", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-16.1.2.tgz", + "integrity": "sha512-0ZiEtJNwYUQewMXxMf2cNHl6N8ZroxC+WS7I6uq3QhPxhbiF0mThRyhRd158rfSVSLEFWKlyZbDQh1ECMSWhDQ==", "dependencies": { "tslib": "^2.3.0" }, @@ -723,16 +791,16 @@ "node": "^16.14.0 || >=18.10.0" }, "peerDependencies": { - "@angular/common": "16.0.1", - "@angular/core": "16.0.1", - "@angular/platform-browser": "16.0.1", + "@angular/common": "16.1.2", + "@angular/core": "16.1.2", + "@angular/platform-browser": "16.1.2", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/service-worker": { - "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==", + "version": "16.1.2", + "resolved": "https://registry.npmjs.org/@angular/service-worker/-/service-worker-16.1.2.tgz", + "integrity": "sha512-9GsaAu88fYMXS3xre0ZezpjdOPB2nhHaqwvW97xBkXBEeMx1kyxyfN7LjDkVdYIaTRM4HMP92jbSirT6CifAfA==", "dependencies": { "tslib": "^2.3.0" }, @@ -743,8 +811,8 @@ "node": "^16.14.0 || >=18.10.0" }, "peerDependencies": { - "@angular/common": "16.0.1", - "@angular/core": "16.0.1" + "@angular/common": "16.1.2", + "@angular/core": "16.1.2" } }, "node_modules/@assemblyscript/loader": { @@ -754,42 +822,42 @@ "dev": true }, "node_modules/@babel/code-frame": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz", - "integrity": "sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz", + "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==", "dev": true, "dependencies": { - "@babel/highlight": "^7.18.6" + "@babel/highlight": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/compat-data": { - "version": "7.21.7", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.7.tgz", - "integrity": "sha512-KYMqFYTaenzMK4yUtf4EW9wc4N9ef80FsbMtkwool5zpwl4YrT1SdWYSTRcT94KO4hannogdS+LxY7L+arP3gA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.5.tgz", + "integrity": "sha512-4Jc/YuIaYqKnDDz892kPIledykKg12Aw1PYX5i/TY28anJtacvM1Rrr8wbieB9GfEJwlzqT0hUEao0CxEebiDA==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.4.tgz", - "integrity": "sha512-qt/YV149Jman/6AfmlxJ04LMIu8bMoyl3RB91yTFrxQmgbrSvQMy7cI8Q62FHx1t8wJ8B5fu0UDoLwHAhUo1QA==", + "version": "7.21.8", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.8.tgz", + "integrity": "sha512-YeM22Sondbo523Sz0+CirSPnbj9bG3P0CdHcBZdqUuaeOaYEFbOLoGU7lebvGP6P5J/WE9wOn7u7C4J9HvS1xQ==", "dev": true, "dependencies": { "@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/generator": "^7.21.5", + "@babel/helper-compilation-targets": "^7.21.5", + "@babel/helper-module-transforms": "^7.21.5", + "@babel/helpers": "^7.21.5", + "@babel/parser": "^7.21.8", "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.4", - "@babel/types": "^7.21.4", + "@babel/traverse": "^7.21.5", + "@babel/types": "^7.21.5", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -814,12 +882,12 @@ } }, "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.22.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.5.tgz", + "integrity": "sha512-+lcUbnTRhd0jOewtFSedLyiPsD5tswKkbgcezOqqWFUVNEwoUTlpPOBmvhG7OXWLR4jMdv0czPGH5XbflnD1EA==", "dev": true, "dependencies": { - "@babel/types": "^7.21.4", + "@babel/types": "^7.22.5", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -829,37 +897,37 @@ } }, "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", - "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", + "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", "dev": true, "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "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==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.5.tgz", + "integrity": "sha512-m1EP3lVOPptR+2DwD125gziZNcmoNSHGmJROKoy87loWUQyJaVXDgpmruWqDARZSmtYQ+Dl25okU8+qhVzuykw==", "dev": true, "dependencies": { - "@babel/types": "^7.21.5" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-compilation-targets": { - "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==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.5.tgz", + "integrity": "sha512-Ji+ywpHeuqxB8WDxraCiqR0xfhYjiDE/e6k7FuIaANnoOFxAHskHChz4vA1mJC9Lbm01s1PVAGhQY4FUKSkGZw==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.21.5", - "@babel/helper-validator-option": "^7.21.0", + "@babel/compat-data": "^7.22.5", + "@babel/helper-validator-option": "^7.22.5", "browserslist": "^4.21.3", "lru-cache": "^5.1.1", "semver": "^6.3.0" @@ -881,19 +949,19 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "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==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.5.tgz", + "integrity": "sha512-xkb58MyOYIslxu3gKmVXmjTtUPvBU4odYzbiIQbWwLKIHCsx6UGZGX6F1IznMFVnDdirseUZopzN+ZRt8Xb33Q==", "dev": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.21.5", - "@babel/helper-function-name": "^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.21.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", - "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-member-expression-to-functions": "^7.22.5", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.5", "semver": "^6.3.0" }, "engines": { @@ -913,12 +981,12 @@ } }, "node_modules/@babel/helper-create-regexp-features-plugin": { - "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==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.5.tgz", + "integrity": "sha512-1VpEFOIbMRaXyDeUwUfmTIxExLwQ+zkW+Bh5zXpApA3oQedBx9v/updixWxnx/bZpKw7u8VxWjb/qWpIcmPq8A==", "dev": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-annotate-as-pure": "^7.22.5", "regexpu-core": "^5.3.1", "semver": "^6.3.0" }, @@ -939,9 +1007,9 @@ } }, "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", - "integrity": "sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.0.tgz", + "integrity": "sha512-RnanLx5ETe6aybRi1cO/edaRH+bNYWaryCEmjDDYyNr4wnSzyOp8T0dWipmqVHKEY3AbVKUom50AKSlj1zmKbg==", "dev": true, "dependencies": { "@babel/helper-compilation-targets": "^7.17.7", @@ -965,113 +1033,113 @@ } }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.21.5.tgz", - "integrity": "sha512-IYl4gZ3ETsWocUWgsFZLM5i1BYx9SoemminVEXadgLBa9TdeorzgLKm8wWLA6J1N/kT3Kch8XIk1laNzYoHKvQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz", + "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==", "dev": true, "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", - "integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", + "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", "dev": true, "dependencies": { - "@babel/template": "^7.20.7", - "@babel/types": "^7.21.0" + "@babel/template": "^7.22.5", + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-hoist-variables": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", - "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", "dev": true, "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-member-expression-to-functions": { - "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==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.22.5.tgz", + "integrity": "sha512-aBiH1NKMG0H2cGZqspNvsaBe6wNGjbJjuLy29aU+eDZjSbbN53BaxlpB02xm9v34pLTZ1nIQPFYn2qMZoa5BQQ==", "dev": true, "dependencies": { - "@babel/types": "^7.21.5" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.21.4.tgz", - "integrity": "sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz", + "integrity": "sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==", "dev": true, "dependencies": { - "@babel/types": "^7.21.4" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.5.tgz", - "integrity": "sha512-bI2Z9zBGY2q5yMHoBvJ2a9iX3ZOAzJPm7Q8Yz6YeoUjU/Cvhmi2G4QyTNyPBqqXSgTjUxRg3L0xV45HvkNWWBw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.5.tgz", + "integrity": "sha512-+hGKDt/Ze8GFExiVHno/2dvG5IdstpzCq0y4Qc9OJ25D4q3pKfiIP/4Vp3/JvhDkLKsDK2api3q3fpIgiIF5bw==", "dev": true, "dependencies": { - "@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.5", - "@babel/types": "^7.21.5" + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-module-imports": "^7.22.5", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.5", + "@babel/template": "^7.22.5", + "@babel/traverse": "^7.22.5", + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz", - "integrity": "sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", + "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", "dev": true, "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-plugin-utils": { - "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==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", + "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz", - "integrity": "sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.5.tgz", + "integrity": "sha512-cU0Sq1Rf4Z55fgz7haOakIyM7+x/uCFwXpLPaeRzfoUtAEAuUZjZvFPjL/rk5rW693dIgn2hng1W7xbT7lWT4g==", "dev": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-wrap-function": "^7.18.9", - "@babel/types": "^7.18.9" + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-wrap-function": "^7.22.5", + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1081,121 +1149,121 @@ } }, "node_modules/@babel/helper-replace-supers": { - "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==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.5.tgz", + "integrity": "sha512-aLdNM5I3kdI/V9xGNyKSF3X/gTyMUBohTZ+/3QdQKAA9vxIiy12E+8E2HoOP1/DjeqU+g6as35QHJNMDDYpuCg==", "dev": true, "dependencies": { - "@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.21.5", - "@babel/types": "^7.21.5" + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-member-expression-to-functions": "^7.22.5", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/template": "^7.22.5", + "@babel/traverse": "^7.22.5", + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-simple-access": { - "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==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", "dev": true, "dependencies": { - "@babel/types": "^7.21.5" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz", - "integrity": "sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", + "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", "dev": true, "dependencies": { - "@babel/types": "^7.20.0" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", - "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.5.tgz", + "integrity": "sha512-thqK5QFghPKWLhAV321lxF95yCg2K3Ob5yw+M3VHWfdia0IkPXUtoLH8x/6Fh486QUvzhb8YOWHChTVen2/PoQ==", "dev": true, "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "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==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", + "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz", - "integrity": "sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz", + "integrity": "sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-wrap-function": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.20.5.tgz", - "integrity": "sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.5.tgz", + "integrity": "sha512-bYqLIBSEshYcYQyfks8ewYA8S30yaGSeRslcvKMvoUk6HHPySbxHq9YRi6ghhzEU+yhQv9bP/jXnygkStOcqZw==", "dev": true, "dependencies": { - "@babel/helper-function-name": "^7.19.0", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.5", - "@babel/types": "^7.20.5" + "@babel/helper-function-name": "^7.22.5", + "@babel/template": "^7.22.5", + "@babel/traverse": "^7.22.5", + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.21.5.tgz", - "integrity": "sha512-BSY+JSlHxOmGsPTydUkPf1MdMQ3M81x5xGCOVgWM3G8XH77sJ292Y2oqcp0CbbgxhqBuI46iUz1tT7hqP7EfgA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.5.tgz", + "integrity": "sha512-pSXRmfE1vzcUIDFQcSGA5Mr+GxBV9oiRKDuDxXvWQQBCh8HoIjs/2DlDB7H8smac1IVrB9/xdXj2N3Wol9Cr+Q==", "dev": true, "dependencies": { - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.5", - "@babel/types": "^7.21.5" + "@babel/template": "^7.22.5", + "@babel/traverse": "^7.22.5", + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz", + "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.18.6", + "@babel/helper-validator-identifier": "^7.22.5", "chalk": "^2.0.0", "js-tokens": "^4.0.0" }, @@ -1204,9 +1272,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.21.8", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.8.tgz", - "integrity": "sha512-6zavDGdzG3gUqAdWvlLFfk+36RilI+Pwyuuh7HItyeScCWP3k6i8vKclAQ0bM/0y/Kz/xiwvxhMv9MgTJP5gmA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.5.tgz", + "integrity": "sha512-DFZMC9LJUG9PLOclRC32G63UXwzqS2koQC8dkx+PLdmt1xSePYpbT/NbsrJy8Q/muXz7o/h/d4A7Fuyixm559Q==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -1216,12 +1284,12 @@ } }, "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz", - "integrity": "sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.22.5.tgz", + "integrity": "sha512-NP1M5Rf+u2Gw9qfSO4ihjcTGW5zXTi36ITLd4/EoAcEhIZ0yjMqmftDNl3QC19CX7olhrjpyU454g/2W7X0jvQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1231,14 +1299,14 @@ } }, "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.20.7.tgz", - "integrity": "sha512-sbr9+wNE5aXMBBFBICk01tt7sBf2Oc9ikRFEcem/ZORup9IMUdNhW7/wVLEbbtlWOsEubJet46mHAL2C8+2jKQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.22.5.tgz", + "integrity": "sha512-31Bb65aZaUwqCbWMnZPduIZxCBngHFlzyN6Dq6KAJjtx+lx6ohKHubc61OomYi7XwVD4Ol0XCVz4h+pYFR048g==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", - "@babel/plugin-proposal-optional-chaining": "^7.20.7" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-transform-optional-chaining": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1265,214 +1333,11 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-proposal-class-properties": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", - "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", - "dev": true, - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-class-static-block": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.21.0.tgz", - "integrity": "sha512-XP5G9MWNUskFuP30IfFSEFB0Z6HzLIUcjYM4bYOPHXl7eiJ9HFv8tWj6TXTN5QODiEhDZAeI4hLok2iHFFV4hw==", - "dev": true, - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.21.0", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/plugin-syntax-class-static-block": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.12.0" - } - }, - "node_modules/@babel/plugin-proposal-dynamic-import": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz", - "integrity": "sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-export-namespace-from": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz", - "integrity": "sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-json-strings": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz", - "integrity": "sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-json-strings": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.20.7.tgz", - "integrity": "sha512-y7C7cZgpMIjWlKE5T7eJwp+tnRYM89HmRvWM5EQuB5BoHEONjmQ8lSNmBUwOyy/GFRsohJED51YBF79hE1djug==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", - "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-numeric-separator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", - "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-object-rest-spread": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz", - "integrity": "sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.20.5", - "@babel/helper-compilation-targets": "^7.20.7", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.20.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-optional-catch-binding": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz", - "integrity": "sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-optional-chaining": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz", - "integrity": "sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-private-methods": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz", - "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", - "dev": true, - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-proposal-private-property-in-object": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0.tgz", - "integrity": "sha512-ha4zfehbJjc5MmXBlHec1igel5TJXXLDDRbuJ4+XT2TJcyD9/V1919BA8gMvsdHcNMBy4WBUBiRb3nw/EQUtBw==", + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-create-class-features-plugin": "^7.21.0", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" - }, "engines": { "node": ">=6.9.0" }, @@ -1560,12 +1425,12 @@ } }, "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz", - "integrity": "sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.22.5.tgz", + "integrity": "sha512-rdV97N7KqsRzeNGoWUOK6yUsWarLjE5Su/Snk9IYPU9CwkWHs4t+rTGOvffTR8XGkJMTAdLfO0xVnXm8wugIJg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1574,6 +1439,33 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.22.5.tgz", + "integrity": "sha512-KwvoWDeNKPETmozyFE0P2rOLqh39EoQHNjqizrI5B8Vt0ZNS7M56s7dAiAqbYfiAYOuIzIh96z3iR2ktgu3tEg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-syntax-json-strings": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", @@ -1688,13 +1580,47 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-arrow-functions": { - "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==", + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.21.5" + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.22.5.tgz", + "integrity": "sha512-26lTNXoVRdAnsaDXPpvCNUq+OVWEVC6bx7Vvz9rC53F2bagUWW4u4ii2+h8Fejfh7RYqPxn+libeFBBck9muEw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.22.5.tgz", + "integrity": "sha512-gGOEvFzm3fWoyD5uZq7vVTD57pPJ3PczPUD/xCFGjzBpUosnklmXyKnGQbbbGs1NPNPskFex0j93yKbHt0cHyg==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-remap-async-to-generator": "^7.22.5", + "@babel/plugin-syntax-async-generators": "^7.8.4" }, "engines": { "node": ">=6.9.0" @@ -1704,14 +1630,14 @@ } }, "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.20.7.tgz", - "integrity": "sha512-Uo5gwHPT9vgnSXQxqGtpdufUiWp96gk7yiP4Mp5bm1QMkEmLXBO7PAGYbKoJ6DhAwiNkcHFBol/x5zZZkL/t0Q==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.22.5.tgz", + "integrity": "sha512-b1A8D8ZzE/VhNDoV1MSJTnpKkCG5bJo+19R4o4oy03zM7ws8yEMK755j61Dc3EyvdysbqH5BOOTquJ7ZX9C6vQ==", "dev": true, "dependencies": { - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-remap-async-to-generator": "^7.18.9" + "@babel/helper-module-imports": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-remap-async-to-generator": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1721,12 +1647,12 @@ } }, "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz", - "integrity": "sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.22.5.tgz", + "integrity": "sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1736,12 +1662,12 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.21.0.tgz", - "integrity": "sha512-Mdrbunoh9SxwFZapeHVrwFmri16+oYotcZysSzhNIVDwIAb1UV+kvnxULSYq9J3/q5MDG+4X6w8QVgD1zhBXNQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.22.5.tgz", + "integrity": "sha512-EcACl1i5fSQ6bt+YGuU/XGCeZKStLmyVGytWkpyhCLeQVA0eu6Wtiw92V+I1T/hnezUv7j74dA/Ro69gWcU+hg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1750,20 +1676,53 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-classes": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.21.0.tgz", - "integrity": "sha512-RZhbYTCEUAe6ntPehC4hlslPWosNHDox+vAs4On/mCLRLfoDVHf6hVEd7kuxr1RnHwJmxFfUM3cZiZRmPxJPXQ==", + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.22.5.tgz", + "integrity": "sha512-nDkQ0NfkOhPTq8YCLiWNxp1+f9fCobEjCb0n8WdbNUBc4IB5V7P1QnX9IjpSoquKrXF5SKojHleVNs2vGeHCHQ==", "dev": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-compilation-targets": "^7.20.7", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.21.0", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-replace-supers": "^7.20.7", - "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-create-class-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.22.5.tgz", + "integrity": "sha512-SPToJ5eYZLxlnp1UzdARpOGeC2GbHvr9d/UV0EukuVx8atktg194oe+C5BqQ8jRTkgLRVOPYeXRSBg1IlMoVRA==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.22.5.tgz", + "integrity": "sha512-2edQhLfibpWpsVBx2n/GKOz6JdGQvLruZQfGr9l1qes2KQaWswjBzhQF7UDUZMNaMMQeYnQzxwOMPsbYF7wqPQ==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-compilation-targets": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.5", "globals": "^11.1.0" }, "engines": { @@ -1774,13 +1733,13 @@ } }, "node_modules/@babel/plugin-transform-computed-properties": { - "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==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.22.5.tgz", + "integrity": "sha512-4GHWBgRf0krxPX+AaPtgBAlTgTeZmqDynokHOX7aqqAB4tHs3U2Y02zH6ETFdLZGcg9UQSD1WCmkVrE9ErHeOg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.21.5", - "@babel/template": "^7.20.7" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/template": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1790,12 +1749,12 @@ } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.21.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.21.3.tgz", - "integrity": "sha512-bp6hwMFzuiE4HqYEyoGJ/V2LeIWn+hLVKc4pnj++E5XQptwhtcGmSayM029d/j2X1bPKGTlsyPwAubuU22KhMA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.22.5.tgz", + "integrity": "sha512-GfqcFuGW8vnEqTUBM7UtPd5A4q797LTvvwKxXTgRsFjoqaJiEg9deBG6kWeQYkVEL569NpnmpC0Pkr/8BLKGnQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1805,13 +1764,13 @@ } }, "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz", - "integrity": "sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.22.5.tgz", + "integrity": "sha512-5/Yk9QxCQCl+sOIB1WelKnVRxTJDSAIxtJLL2/pqL14ZVlbH0fUQUZa/T5/UnQtBNgghR7mfB8ERBKyKPCi7Vw==", "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1821,12 +1780,28 @@ } }, "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz", - "integrity": "sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.22.5.tgz", + "integrity": "sha512-dEnYD+9BBgld5VBXHnF/DbYGp3fqGMsyxKbtD1mDyIA7AkTSpKXFhCVuj/oQVOoALfBs77DudA0BE4d5mcpmqw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.22.5.tgz", + "integrity": "sha512-0MC3ppTB1AMxd8fXjSrbPa7LT9hrImt+/fcj+Pg5YMD7UQyWp/02+JWpdnCymmsXwIx5Z+sYn1bwCn4ZJNvhqQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" }, "engines": { "node": ">=6.9.0" @@ -1836,13 +1811,29 @@ } }, "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz", - "integrity": "sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.22.5.tgz", + "integrity": "sha512-vIpJFNM/FjZ4rh1myqIya9jXwrwwgFRHPjT3DkUA9ZLHuzox8jiXkOLvwm1H+PQIP3CqfC++WPKeuDi0Sjdj1g==", "dev": true, "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.22.5.tgz", + "integrity": "sha512-X4hhm7FRnPgd4nDA4b/5V280xCx6oL7Oob5+9qVS5C13Zq4bh1qq7LU0GgRU6b5dBWBvhGaXYVB4AcN6+ol6vg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" }, "engines": { "node": ">=6.9.0" @@ -1852,12 +1843,12 @@ } }, "node_modules/@babel/plugin-transform-for-of": { - "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==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.22.5.tgz", + "integrity": "sha512-3kxQjX1dU9uudwSshyLeEipvrLjBCVthCgeTp6CzE/9JYrlAIaeekVxRpCWsDDfYTfRZRoCeZatCQvwo+wvK8A==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.21.5" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1867,14 +1858,30 @@ } }, "node_modules/@babel/plugin-transform-function-name": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz", - "integrity": "sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.22.5.tgz", + "integrity": "sha512-UIzQNMS0p0HHiQm3oelztj+ECwFnj+ZRV4KnguvlsD2of1whUeM6o7wGNj6oLwcDoAXQ8gEqfgC24D+VdIcevg==", "dev": true, "dependencies": { - "@babel/helper-compilation-targets": "^7.18.9", - "@babel/helper-function-name": "^7.18.9", - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-compilation-targets": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.22.5.tgz", + "integrity": "sha512-DuCRB7fu8MyTLbEQd1ew3R85nx/88yMoqo2uPSjevMj3yoN7CDM8jkgrY0wmVxfJZyJ/B9fE1iq7EQppWQmR5A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-json-strings": "^7.8.3" }, "engines": { "node": ">=6.9.0" @@ -1884,12 +1891,28 @@ } }, "node_modules/@babel/plugin-transform-literals": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz", - "integrity": "sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.22.5.tgz", + "integrity": "sha512-fTLj4D79M+mepcw3dgFBTIDYpbcB9Sm0bpm4ppXPaO+U+PKFFyV9MGRvS0gvGw62sd10kT5lRMKXAADb9pWy8g==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.22.5.tgz", + "integrity": "sha512-MQQOUW1KL8X0cDWfbwYP+TbVbZm16QmQXJQ+vndPtH/BoO0lOKpVoEDMI7+PskYxH+IiE0tS8xZye0qr1lGzSA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" }, "engines": { "node": ">=6.9.0" @@ -1899,12 +1922,12 @@ } }, "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz", - "integrity": "sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.22.5.tgz", + "integrity": "sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1914,13 +1937,13 @@ } }, "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.20.11", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.20.11.tgz", - "integrity": "sha512-NuzCt5IIYOW0O30UvqktzHYR2ud5bOWbY0yaxWZ6G+aFzOMJvrs5YHNikrbdaT15+KNO31nPOy5Fim3ku6Zb5g==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.22.5.tgz", + "integrity": "sha512-R+PTfLTcYEmb1+kK7FNkhQ1gP4KgjpSO6HfH9+f8/yfp2Nt3ggBjiVpRwmwTlfqZLafYKJACy36yDXlEmI9HjQ==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.20.11", - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-module-transforms": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1930,14 +1953,14 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "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==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.22.5.tgz", + "integrity": "sha512-B4pzOXj+ONRmuaQTg05b3y/4DuFz3WcCNAXPLb2Q0GT0TrGKGxNKV4jwsXts+StaM0LQczZbOpj8o1DLPDJIiA==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.21.5", - "@babel/helper-plugin-utils": "^7.21.5", - "@babel/helper-simple-access": "^7.21.5" + "@babel/helper-module-transforms": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-simple-access": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1947,15 +1970,15 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.20.11", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.20.11.tgz", - "integrity": "sha512-vVu5g9BPQKSFEmvt2TA4Da5N+QVS66EX21d8uoOihC+OCpUoGvzVsXeqFdtAEfVa5BILAeFt+U7yVmLbQnAJmw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.22.5.tgz", + "integrity": "sha512-emtEpoaTMsOs6Tzz+nbmcePl6AKVtS1yC4YNAeMun9U8YCsgadPNxnOPQ8GhHFB2qdx+LZu9LgoC0Lthuu05DQ==", "dev": true, "dependencies": { - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-module-transforms": "^7.20.11", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-validator-identifier": "^7.19.1" + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-module-transforms": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1965,13 +1988,13 @@ } }, "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz", - "integrity": "sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.22.5.tgz", + "integrity": "sha512-+S6kzefN/E1vkSsKx8kmQuqeQsvCKCd1fraCM7zXm4SFoggI099Tr4G8U81+5gtMdUeMQ4ipdQffbKLX0/7dBQ==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-module-transforms": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1981,13 +2004,13 @@ } }, "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.20.5.tgz", - "integrity": "sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz", + "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==", "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.20.5", - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1997,12 +2020,63 @@ } }, "node_modules/@babel/plugin-transform-new-target": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz", - "integrity": "sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.22.5.tgz", + "integrity": "sha512-AsF7K0Fx/cNKVyk3a+DW0JLo+Ua598/NxMRvxDnkpCIGFh43+h/v2xyhRUYf6oD8gE4QtL83C7zZVghMjHd+iw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.22.5.tgz", + "integrity": "sha512-6CF8g6z1dNYZ/VXok5uYkkBBICHZPiGEl7oDnAx2Mt1hlHVHOSIKWJaXHjQJA5VB43KZnXZDIexMchY4y2PGdA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.22.5.tgz", + "integrity": "sha512-NbslED1/6M+sXiwwtcAB/nieypGw02Ejf4KtDeMkCEpP6gWFMX1wI9WKYua+4oBneCCEmulOkRpwywypVZzs/g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.5.tgz", + "integrity": "sha512-Kk3lyDmEslH9DnvCDA1s1kkd3YWQITiBOHngOtDL9Pt6BZjzqb6hiOlb8VfjiiQJ2unmegBqZu0rx5RxJb5vmQ==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.22.5", + "@babel/helper-compilation-targets": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -2012,13 +2086,46 @@ } }, "node_modules/@babel/plugin-transform-object-super": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz", - "integrity": "sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.22.5.tgz", + "integrity": "sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-replace-supers": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.22.5.tgz", + "integrity": "sha512-pH8orJahy+hzZje5b8e2QIlBWQvGpelS76C63Z+jhZKsmzfNaPQ+LaW6dcJ9bxTpo1mtXbgHwy765Ro3jftmUg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.22.5.tgz", + "integrity": "sha512-AconbMKOMkyG+xCng2JogMCDcqW8wedQAqpVIL4cOSescZ7+iW8utC6YDZLMCSUIReEA733gzRSaOSXMAt/4WQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" }, "engines": { "node": ">=6.9.0" @@ -2028,12 +2135,46 @@ } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.21.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.21.3.tgz", - "integrity": "sha512-Wxc+TvppQG9xWFYatvCGPvZ6+SIUxQ2ZdiBP+PHYMIjnPXD+uThCshaz4NZOnODAtBjjcVQQ/3OKs9LW28purQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.22.5.tgz", + "integrity": "sha512-AVkFUBurORBREOmHRKo06FjHYgjrabpdqRSwq6+C7R5iTCZOsM4QbcB27St0a4U6fffyAOqh3s/qEfybAhfivg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.22.5.tgz", + "integrity": "sha512-PPjh4gyrQnGe97JTalgRGMuU4icsZFnWkzicB/fUtzlKUqvsWBKEpPPfr5a2JiyirZkHxnAqkQMO5Z5B2kK3fA==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.22.5.tgz", + "integrity": "sha512-/9xnaTTJcVoBtSSmrVyhtSvO3kbqS2ODoh2juEU72c3aYonNF0OMGiaz2gjukyKM2wBBYJP38S4JiE0Wfb5VMQ==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" }, "engines": { "node": ">=6.9.0" @@ -2043,12 +2184,12 @@ } }, "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz", - "integrity": "sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.22.5.tgz", + "integrity": "sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -2058,12 +2199,12 @@ } }, "node_modules/@babel/plugin-transform-regenerator": { - "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==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.22.5.tgz", + "integrity": "sha512-rR7KePOE7gfEtNTh9Qw+iO3Q/e4DEsoQ+hdvM6QUDH7JRJ5qxq5AA52ZzBWbI5i9lfNuvySgOGP8ZN7LAmaiPw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.21.5", + "@babel/helper-plugin-utils": "^7.22.5", "regenerator-transform": "^0.15.1" }, "engines": { @@ -2074,12 +2215,12 @@ } }, "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz", - "integrity": "sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.22.5.tgz", + "integrity": "sha512-DTtGKFRQUDm8svigJzZHzb/2xatPc6TzNvAIJ5GqOKDsGFYgAskjRulbR/vGsPKq3OPqtexnz327qYpP57RFyA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -2089,16 +2230,16 @@ } }, "node_modules/@babel/plugin-transform-runtime": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.21.4.tgz", - "integrity": "sha512-1J4dhrw1h1PqnNNpzwxQ2UBymJUF8KuPjAAnlLwZcGhHAIqUigFW7cdK6GHoB64ubY4qXQNYknoUeks4Wz7CUA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.22.5.tgz", + "integrity": "sha512-bg4Wxd1FWeFx3daHFTWk1pkSWK/AyQuiyAoeZAOkAOUBjnZPH6KT7eMxouV47tQ6hl6ax2zyAWBdWZXbrvXlaw==", "dev": true, "dependencies": { - "@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", + "@babel/helper-module-imports": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "babel-plugin-polyfill-corejs2": "^0.4.3", + "babel-plugin-polyfill-corejs3": "^0.8.1", + "babel-plugin-polyfill-regenerator": "^0.5.0", "semver": "^6.3.0" }, "engines": { @@ -2118,12 +2259,12 @@ } }, "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz", - "integrity": "sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.22.5.tgz", + "integrity": "sha512-vM4fq9IXHscXVKzDv5itkO1X52SmdFBFcMIBZ2FRn2nqVYqw6dBexUgMvAjHW+KXpPPViD/Yo3GrDEBaRC0QYA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -2133,13 +2274,13 @@ } }, "node_modules/@babel/plugin-transform-spread": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.20.7.tgz", - "integrity": "sha512-ewBbHQ+1U/VnH1fxltbJqDeWBU1oNLG8Dj11uIv3xVf7nrQu0bPGe5Rf716r7K5Qz+SqtAOVswoVunoiBtGhxw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.22.5.tgz", + "integrity": "sha512-5ZzDQIGyvN4w8+dMmpohL6MBo+l2G7tfC/O2Dg7/hjpgeWvUx8FzfeOKxGog9IimPa4YekaQ9PlDqTLOljkcxg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -2149,12 +2290,12 @@ } }, "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz", - "integrity": "sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.22.5.tgz", + "integrity": "sha512-zf7LuNpHG0iEeiyCNwX4j3gDg1jgt1k3ZdXBKbZSoA3BbGQGvMiSvfbZRR3Dr3aeJe3ooWFZxOOG3IRStYp2Bw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -2164,12 +2305,12 @@ } }, "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz", - "integrity": "sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.22.5.tgz", + "integrity": "sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -2179,12 +2320,12 @@ } }, "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz", - "integrity": "sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.22.5.tgz", + "integrity": "sha512-bYkI5lMzL4kPii4HHEEChkD0rkc+nvnlR6+o/qdqR6zrm0Sv/nodmyLhlq2DO0YKLUNd2VePmPRjJXSBh9OIdA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -2194,12 +2335,28 @@ } }, "node_modules/@babel/plugin-transform-unicode-escapes": { - "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==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.22.5.tgz", + "integrity": "sha512-biEmVg1IYB/raUO5wT1tgfacCef15Fbzhkx493D3urBI++6hpJ+RFG4SrWMn0NEZLfvilqKf3QDrRVZHo08FYg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.21.5" + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.22.5.tgz", + "integrity": "sha512-HCCIb+CbJIAE6sXn5CjFQXMwkCClcOfPCzTlilJ8cUatfzwHlWQkbtV0zD338u9dZskwvuOYTuuaMaA8J5EI5A==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -2209,13 +2366,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz", - "integrity": "sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.22.5.tgz", + "integrity": "sha512-028laaOKptN5vHJf9/Arr/HiJekMd41hOEZYvNsrsXqJ7YPYuX2bQxh31fkZzGmq3YqHRJzYFFAVYvKfMPKqyg==", "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -2224,39 +2381,43 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/preset-env": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.21.4.tgz", - "integrity": "sha512-2W57zHs2yDLm6GD5ZpvNn71lZ0B/iypSdIeq25OurDKji6AdzV07qp4s3n1/x5BqtiGaTrPN3nerlSCaC5qNTw==", + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.22.5.tgz", + "integrity": "sha512-lhMfi4FC15j13eKrh3DnYHjpGj6UKQHtNKTbtc1igvAhRy4+kLhV07OpLcsN0VgDEw/MjAvJO4BdMJsHwMhzCg==", "dev": true, "dependencies": { - "@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.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.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.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.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.7", - "@babel/plugin-proposal-optional-catch-binding": "^7.18.6", - "@babel/plugin-proposal-optional-chaining": "^7.21.0", - "@babel/plugin-proposal-private-methods": "^7.18.6", - "@babel/plugin-proposal-private-property-in-object": "^7.21.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.18.6", + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.22.5.tgz", + "integrity": "sha512-fj06hw89dpiZzGZtxn+QybifF07nNiZjZ7sazs2aVDcysAZVGjW7+7iFYxg6GLNM47R/thYfLdrXc+2f11Vi9A==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.22.5", + "@babel/helper-compilation-targets": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.22.5", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.22.5", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.22.5", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-class-properties": "^7.12.13", "@babel/plugin-syntax-class-static-block": "^7.14.5", "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.20.0", + "@babel/plugin-syntax-import-assertions": "^7.22.5", + "@babel/plugin-syntax-import-attributes": "^7.22.5", + "@babel/plugin-syntax-import-meta": "^7.10.4", "@babel/plugin-syntax-json-strings": "^7.8.3", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", @@ -2266,44 +2427,61 @@ "@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.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.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.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.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.20.5", - "@babel/plugin-transform-new-target": "^7.18.6", - "@babel/plugin-transform-object-super": "^7.18.6", - "@babel/plugin-transform-parameters": "^7.21.3", - "@babel/plugin-transform-property-literals": "^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.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/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.22.5", + "@babel/plugin-transform-async-generator-functions": "^7.22.5", + "@babel/plugin-transform-async-to-generator": "^7.22.5", + "@babel/plugin-transform-block-scoped-functions": "^7.22.5", + "@babel/plugin-transform-block-scoping": "^7.22.5", + "@babel/plugin-transform-class-properties": "^7.22.5", + "@babel/plugin-transform-class-static-block": "^7.22.5", + "@babel/plugin-transform-classes": "^7.22.5", + "@babel/plugin-transform-computed-properties": "^7.22.5", + "@babel/plugin-transform-destructuring": "^7.22.5", + "@babel/plugin-transform-dotall-regex": "^7.22.5", + "@babel/plugin-transform-duplicate-keys": "^7.22.5", + "@babel/plugin-transform-dynamic-import": "^7.22.5", + "@babel/plugin-transform-exponentiation-operator": "^7.22.5", + "@babel/plugin-transform-export-namespace-from": "^7.22.5", + "@babel/plugin-transform-for-of": "^7.22.5", + "@babel/plugin-transform-function-name": "^7.22.5", + "@babel/plugin-transform-json-strings": "^7.22.5", + "@babel/plugin-transform-literals": "^7.22.5", + "@babel/plugin-transform-logical-assignment-operators": "^7.22.5", + "@babel/plugin-transform-member-expression-literals": "^7.22.5", + "@babel/plugin-transform-modules-amd": "^7.22.5", + "@babel/plugin-transform-modules-commonjs": "^7.22.5", + "@babel/plugin-transform-modules-systemjs": "^7.22.5", + "@babel/plugin-transform-modules-umd": "^7.22.5", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", + "@babel/plugin-transform-new-target": "^7.22.5", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.22.5", + "@babel/plugin-transform-numeric-separator": "^7.22.5", + "@babel/plugin-transform-object-rest-spread": "^7.22.5", + "@babel/plugin-transform-object-super": "^7.22.5", + "@babel/plugin-transform-optional-catch-binding": "^7.22.5", + "@babel/plugin-transform-optional-chaining": "^7.22.5", + "@babel/plugin-transform-parameters": "^7.22.5", + "@babel/plugin-transform-private-methods": "^7.22.5", + "@babel/plugin-transform-private-property-in-object": "^7.22.5", + "@babel/plugin-transform-property-literals": "^7.22.5", + "@babel/plugin-transform-regenerator": "^7.22.5", + "@babel/plugin-transform-reserved-words": "^7.22.5", + "@babel/plugin-transform-shorthand-properties": "^7.22.5", + "@babel/plugin-transform-spread": "^7.22.5", + "@babel/plugin-transform-sticky-regex": "^7.22.5", + "@babel/plugin-transform-template-literals": "^7.22.5", + "@babel/plugin-transform-typeof-symbol": "^7.22.5", + "@babel/plugin-transform-unicode-escapes": "^7.22.5", + "@babel/plugin-transform-unicode-property-regex": "^7.22.5", + "@babel/plugin-transform-unicode-regex": "^7.22.5", + "@babel/plugin-transform-unicode-sets-regex": "^7.22.5", "@babel/preset-modules": "^0.1.5", - "@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", - "core-js-compat": "^3.25.1", + "@babel/types": "^7.22.5", + "babel-plugin-polyfill-corejs2": "^0.4.3", + "babel-plugin-polyfill-corejs3": "^0.8.1", + "babel-plugin-polyfill-regenerator": "^0.5.0", + "core-js-compat": "^3.30.2", "semver": "^6.3.0" }, "engines": { @@ -2345,9 +2523,9 @@ "dev": true }, "node_modules/@babel/runtime": { - "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==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.5.tgz", + "integrity": "sha512-ecjvYlnAaZ/KVneE/OdKYBYfgXV3Ptu6zQWmgEF7vwKhQnvVS6bjMD2XYgj+SNvQ1GfK/pjgokfPkC/2CO8CuA==", "dev": true, "dependencies": { "regenerator-runtime": "^0.13.11" @@ -2357,33 +2535,33 @@ } }, "node_modules/@babel/template": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", - "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", + "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7" + "@babel/code-frame": "^7.22.5", + "@babel/parser": "^7.22.5", + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.5.tgz", - "integrity": "sha512-AhQoI3YjWi6u/y/ntv7k48mcrCXmus0t79J9qPNlk/lAsFlCiJ047RmbfMOawySTHtywXhbXgpx/8nXMYd+oFw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.5.tgz", + "integrity": "sha512-7DuIjPgERaNo6r+PZwItpjCZEa5vyw4eJGufeLxrPdBXBoLcCJCIasvK6pK/9DVNrLZTLFhUGqaC6X/PA007TQ==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.21.4", - "@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.5", - "@babel/types": "^7.21.5", + "@babel/code-frame": "^7.22.5", + "@babel/generator": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.5", + "@babel/parser": "^7.22.5", + "@babel/types": "^7.22.5", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -2391,29 +2569,14 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/traverse/node_modules/@babel/generator": { - "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.5", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", - "jsesc": "^2.5.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/types": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.5.tgz", - "integrity": "sha512-m4AfNvVF2mVC/F7fDEdH2El3HzUg9It/XsCxZiOTTA3m3qYfcSVSbTfM6Q9xG+hYDniZssYhlXKKUMD5m8tF4Q==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.5.tgz", + "integrity": "sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==", "dev": true, "dependencies": { - "@babel/helper-string-parser": "^7.21.5", - "@babel/helper-validator-identifier": "^7.19.1", + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.5", "to-fast-properties": "^2.0.0" }, "engines": { @@ -2443,22 +2606,6 @@ "@bufbuild/buf-win32-x64": "1.18.0-1" } }, - "node_modules/@bufbuild/buf-darwin-arm64": { - "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" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/@bufbuild/buf-darwin-x64": { "version": "1.18.0-1", "resolved": "https://registry.npmjs.org/@bufbuild/buf-darwin-x64/-/buf-darwin-x64-1.18.0-1.tgz", @@ -2475,70 +2622,6 @@ "node": ">=12" } }, - "node_modules/@bufbuild/buf-linux-aarch64": { - "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" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@bufbuild/buf-linux-x64": { - "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" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@bufbuild/buf-win32-arm64": { - "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" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@bufbuild/buf-win32-x64": { - "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" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/@colors/colors": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", @@ -2548,30 +2631,6 @@ "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", @@ -2603,74 +2662,10 @@ "node": ">=10.0.0" } }, - "node_modules/@esbuild/android-arm": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.18.tgz", - "integrity": "sha512-EmwL+vUBZJ7mhFCs5lA4ZimpUH3WMAoqvOIYhVQwdIgSpHC8ImHdsRyhHAVxpDYUSm0lWvd63z0XH1IlImS2Qw==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "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" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "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" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "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" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/@esbuild/darwin-x64": { - "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==", + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.19.tgz", + "integrity": "sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==", "cpu": [ "x64" ], @@ -2683,278 +2678,6 @@ "node": ">=12" } }, - "node_modules/@esbuild/freebsd-arm64": { - "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" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "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" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "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" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "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" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.18.tgz", - "integrity": "sha512-ygIMc3I7wxgXIxk6j3V00VlABIjq260i967Cp9BNAk5pOOpIXmd1RFQJQX9Io7KRsthDrQYrtcx7QCof4o3ZoQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.18.tgz", - "integrity": "sha512-bvPG+MyFs5ZlwYclCG1D744oHk1Pv7j8psF5TfYx7otCVmcJsEXgFEhQkbhNW8otDHL1a2KDINW20cfCgnzgMQ==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.18.tgz", - "integrity": "sha512-oVqckATOAGuiUOa6wr8TXaVPSa+6IwVJrGidmNZS1cZVx0HqkTMkqFGD2HIx9H1RvOwFeWYdaYbdY6B89KUMxA==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "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" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "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" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "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" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.18.tgz", - "integrity": "sha512-66RmRsPlYy4jFl0vG80GcNRdirx4nVWAzJmXkevgphP1qf4dsLQCpSKGM3DUQCojwU1hnepI63gNZdrr02wHUA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.18.tgz", - "integrity": "sha512-95IRY7mI2yrkLlTLb1gpDxdC5WLC5mZDi+kA9dmM5XAGxCME0F8i4bYH4jZreaJ6lIZ0B8hTrweqG1fUyW7jbg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.18.tgz", - "integrity": "sha512-WevVOgcng+8hSZ4Q3BKL3n1xTv5H6Nb53cBrtzzEjDbbnOmucEVcZeGCsCOi9bAOcDYEeBZbD2SJNBxlfP3qiA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "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" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "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" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "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" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.18.tgz", - "integrity": "sha512-qU25Ma1I3NqTSHJUOKi9sAH1/Mzuvlke0ioMJRthLXKm7JiSKVwFghlGbDLOO2sARECGhja4xYfRAZNPAkooYg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -3078,12 +2801,6 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/@gar/promisify": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", - "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", - "dev": true - }, "node_modules/@grpc/grpc-js": { "version": "1.8.14", "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.8.14.tgz", @@ -3212,9 +2929,9 @@ } }, "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==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, "dependencies": { "ansi-regex": "^6.0.1" @@ -3339,761 +3056,761 @@ "dev": true }, "node_modules/@material/animation": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/animation/-/animation-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-tr1y4KYZ2Ml9lFU9b91r5jivDCbh0N3Zv6VFe0frphztlZO5Lqx7MCxsliQ7NwQjqpXg3MkD6ZusVNvnMyo+LA==", "dependencies": { "tslib": "^2.1.0" } }, "node_modules/@material/auto-init": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/auto-init/-/auto-init-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-ZslBlje2LajaL5d7JCxUoWCKOBOsZYT33CamqPoDeY0Cjl77t3O+8B9YPHF8libytI8j9lrrDrTItQr53PHeHw==", "dependencies": { - "@material/base": "15.0.0-canary.3b5b55e31.0", + "@material/base": "15.0.0-canary.90291f2e2.0", "tslib": "^2.1.0" } }, "node_modules/@material/banner": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/banner/-/banner-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-mVtGop9rBXRD6UYkMD7y+OJwd3MA73w7BJ/oJIKFij2q2fn/5hZba6vQ6d6YGUGv+iJPP/S/HaiMQuRE5yyoqA==", "dependencies": { - "@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", + "@material/base": "15.0.0-canary.90291f2e2.0", + "@material/button": "15.0.0-canary.90291f2e2.0", + "@material/dom": "15.0.0-canary.90291f2e2.0", + "@material/elevation": "15.0.0-canary.90291f2e2.0", + "@material/feature-targeting": "15.0.0-canary.90291f2e2.0", + "@material/ripple": "15.0.0-canary.90291f2e2.0", + "@material/rtl": "15.0.0-canary.90291f2e2.0", + "@material/shape": "15.0.0-canary.90291f2e2.0", + "@material/theme": "15.0.0-canary.90291f2e2.0", + "@material/tokens": "15.0.0-canary.90291f2e2.0", + "@material/typography": "15.0.0-canary.90291f2e2.0", "tslib": "^2.1.0" } }, "node_modules/@material/base": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/base/-/base-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-DNelmohDScmGvWWS/J05dkIJb/dKOVkA6s0URgPrnTFKXNSavPsmwj7hWzYB5kusz3ZrXJBYBJsE6VqkRRXl0w==", "dependencies": { "tslib": "^2.1.0" } }, "node_modules/@material/button": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/button/-/button-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-m3YqCh33kcPGYehCKviDy7RxQIEM2m8Exo6AswPPsxd95jSN3rAeF+pXopoXW5QTOqyKHqHymTKTRYYvwvZHYg==", "dependencies": { - "@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", + "@material/density": "15.0.0-canary.90291f2e2.0", + "@material/dom": "15.0.0-canary.90291f2e2.0", + "@material/elevation": "15.0.0-canary.90291f2e2.0", + "@material/feature-targeting": "15.0.0-canary.90291f2e2.0", + "@material/focus-ring": "15.0.0-canary.90291f2e2.0", + "@material/ripple": "15.0.0-canary.90291f2e2.0", + "@material/rtl": "15.0.0-canary.90291f2e2.0", + "@material/shape": "15.0.0-canary.90291f2e2.0", + "@material/theme": "15.0.0-canary.90291f2e2.0", + "@material/tokens": "15.0.0-canary.90291f2e2.0", + "@material/touch-target": "15.0.0-canary.90291f2e2.0", + "@material/typography": "15.0.0-canary.90291f2e2.0", "tslib": "^2.1.0" } }, "node_modules/@material/card": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/card/-/card-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-8Z8KQDmEIwt5IK0n+9C9Be9p4mWLKBXILbH+c6XcMCTemmUxH6cTTax1MwuAmqBGuIq3WE3g7qDpdzjFLTC2kw==", "dependencies": { - "@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/dom": "15.0.0-canary.90291f2e2.0", + "@material/elevation": "15.0.0-canary.90291f2e2.0", + "@material/feature-targeting": "15.0.0-canary.90291f2e2.0", + "@material/ripple": "15.0.0-canary.90291f2e2.0", + "@material/rtl": "15.0.0-canary.90291f2e2.0", + "@material/shape": "15.0.0-canary.90291f2e2.0", + "@material/theme": "15.0.0-canary.90291f2e2.0", + "@material/tokens": "15.0.0-canary.90291f2e2.0", "tslib": "^2.1.0" } }, "node_modules/@material/checkbox": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/checkbox/-/checkbox-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-hCilHX0vLedMgeRSOskf+JjdfLIUvEg597LEkTJHnTtJkhwypvol8OwP3eqz3TyJ3qGimIi/sFPKdMBn1Uk4AQ==", "dependencies": { - "@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", + "@material/animation": "15.0.0-canary.90291f2e2.0", + "@material/base": "15.0.0-canary.90291f2e2.0", + "@material/density": "15.0.0-canary.90291f2e2.0", + "@material/dom": "15.0.0-canary.90291f2e2.0", + "@material/feature-targeting": "15.0.0-canary.90291f2e2.0", + "@material/focus-ring": "15.0.0-canary.90291f2e2.0", + "@material/ripple": "15.0.0-canary.90291f2e2.0", + "@material/rtl": "15.0.0-canary.90291f2e2.0", + "@material/theme": "15.0.0-canary.90291f2e2.0", + "@material/touch-target": "15.0.0-canary.90291f2e2.0", "tslib": "^2.1.0" } }, "node_modules/@material/chips": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/chips/-/chips-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-TMtlzuadWP/YMRYg8mpqmaD9M9GzRL5ulHHgYO5F4kaZmI3L+3zvaPvUme/x5qwPkIJUO9S21NxxGAsp9X+ZJQ==", "dependencies": { - "@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", + "@material/animation": "15.0.0-canary.90291f2e2.0", + "@material/base": "15.0.0-canary.90291f2e2.0", + "@material/checkbox": "15.0.0-canary.90291f2e2.0", + "@material/density": "15.0.0-canary.90291f2e2.0", + "@material/dom": "15.0.0-canary.90291f2e2.0", + "@material/elevation": "15.0.0-canary.90291f2e2.0", + "@material/feature-targeting": "15.0.0-canary.90291f2e2.0", + "@material/focus-ring": "15.0.0-canary.90291f2e2.0", + "@material/ripple": "15.0.0-canary.90291f2e2.0", + "@material/rtl": "15.0.0-canary.90291f2e2.0", + "@material/shape": "15.0.0-canary.90291f2e2.0", + "@material/theme": "15.0.0-canary.90291f2e2.0", + "@material/tokens": "15.0.0-canary.90291f2e2.0", + "@material/touch-target": "15.0.0-canary.90291f2e2.0", + "@material/typography": "15.0.0-canary.90291f2e2.0", "safevalues": "^0.3.4", "tslib": "^2.1.0" } }, "node_modules/@material/circular-progress": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/circular-progress/-/circular-progress-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-znCz3cXC8rmC+1k1ZEeZNOhngm7O7kVG2PoANaE79NN9taDtCTyBGGeocJ4Kza3tb01vxJ2/tuQXC39GNFkHFg==", "dependencies": { - "@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", + "@material/animation": "15.0.0-canary.90291f2e2.0", + "@material/base": "15.0.0-canary.90291f2e2.0", + "@material/dom": "15.0.0-canary.90291f2e2.0", + "@material/feature-targeting": "15.0.0-canary.90291f2e2.0", + "@material/progress-indicator": "15.0.0-canary.90291f2e2.0", + "@material/rtl": "15.0.0-canary.90291f2e2.0", + "@material/theme": "15.0.0-canary.90291f2e2.0", "tslib": "^2.1.0" } }, "node_modules/@material/data-table": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/data-table/-/data-table-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-9YU6KkOeKs2ARPXZdg7Cv6nPwLkEyBIN331ZB92apcbQpTMJMhR3uuW8SSw4p7aXCE6CJjREsCc0KuYAnFSa2A==", "dependencies": { - "@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", + "@material/animation": "15.0.0-canary.90291f2e2.0", + "@material/base": "15.0.0-canary.90291f2e2.0", + "@material/checkbox": "15.0.0-canary.90291f2e2.0", + "@material/density": "15.0.0-canary.90291f2e2.0", + "@material/dom": "15.0.0-canary.90291f2e2.0", + "@material/elevation": "15.0.0-canary.90291f2e2.0", + "@material/feature-targeting": "15.0.0-canary.90291f2e2.0", + "@material/icon-button": "15.0.0-canary.90291f2e2.0", + "@material/linear-progress": "15.0.0-canary.90291f2e2.0", + "@material/list": "15.0.0-canary.90291f2e2.0", + "@material/menu": "15.0.0-canary.90291f2e2.0", + "@material/rtl": "15.0.0-canary.90291f2e2.0", + "@material/select": "15.0.0-canary.90291f2e2.0", + "@material/shape": "15.0.0-canary.90291f2e2.0", + "@material/theme": "15.0.0-canary.90291f2e2.0", + "@material/tokens": "15.0.0-canary.90291f2e2.0", + "@material/touch-target": "15.0.0-canary.90291f2e2.0", + "@material/typography": "15.0.0-canary.90291f2e2.0", "tslib": "^2.1.0" } }, "node_modules/@material/density": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/density/-/density-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-z2L49vc5tbIGe7tUHwbmzoPvOugsTNVP24WWwBwtg9PRuK4Td5HIsMGYqSzSuwFJvDWQK9Ugvl37jGZSv4vxog==", "dependencies": { "tslib": "^2.1.0" } }, "node_modules/@material/dialog": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/dialog/-/dialog-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-n0o4MELpVqJHbJDPBYeXf3xeL9a8hbzHmfXYLDI1MUhDIr4xgSkckKdCRc2IFda/g7kxjAgcUTga9EFWqns2qA==", "dependencies": { - "@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", + "@material/animation": "15.0.0-canary.90291f2e2.0", + "@material/base": "15.0.0-canary.90291f2e2.0", + "@material/button": "15.0.0-canary.90291f2e2.0", + "@material/dom": "15.0.0-canary.90291f2e2.0", + "@material/elevation": "15.0.0-canary.90291f2e2.0", + "@material/feature-targeting": "15.0.0-canary.90291f2e2.0", + "@material/icon-button": "15.0.0-canary.90291f2e2.0", + "@material/ripple": "15.0.0-canary.90291f2e2.0", + "@material/rtl": "15.0.0-canary.90291f2e2.0", + "@material/shape": "15.0.0-canary.90291f2e2.0", + "@material/theme": "15.0.0-canary.90291f2e2.0", + "@material/tokens": "15.0.0-canary.90291f2e2.0", + "@material/touch-target": "15.0.0-canary.90291f2e2.0", + "@material/typography": "15.0.0-canary.90291f2e2.0", "tslib": "^2.1.0" } }, "node_modules/@material/dom": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/dom/-/dom-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-90JKk/Ncnqn2dKopNxs1uruiiQZzgLTZQF3a8jxa/w3RQd3Ac9ET1KqmaJSfzXaxgebm+1RZfL9lL+ANEfLWwQ==", "dependencies": { - "@material/feature-targeting": "15.0.0-canary.3b5b55e31.0", - "@material/rtl": "15.0.0-canary.3b5b55e31.0", + "@material/feature-targeting": "15.0.0-canary.90291f2e2.0", + "@material/rtl": "15.0.0-canary.90291f2e2.0", "tslib": "^2.1.0" } }, "node_modules/@material/drawer": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/drawer/-/drawer-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-7MJbjUxqpQG9J52xWGVKRhSI/0/7Uhf7l2P9VI2WFb5Fz0IeUupXlw2k1Ktb97nxSjMe9OazjtVUgzBNwOad/Q==", "dependencies": { - "@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", + "@material/animation": "15.0.0-canary.90291f2e2.0", + "@material/base": "15.0.0-canary.90291f2e2.0", + "@material/dom": "15.0.0-canary.90291f2e2.0", + "@material/elevation": "15.0.0-canary.90291f2e2.0", + "@material/feature-targeting": "15.0.0-canary.90291f2e2.0", + "@material/list": "15.0.0-canary.90291f2e2.0", + "@material/ripple": "15.0.0-canary.90291f2e2.0", + "@material/rtl": "15.0.0-canary.90291f2e2.0", + "@material/shape": "15.0.0-canary.90291f2e2.0", + "@material/theme": "15.0.0-canary.90291f2e2.0", + "@material/typography": "15.0.0-canary.90291f2e2.0", "tslib": "^2.1.0" } }, "node_modules/@material/elevation": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/elevation/-/elevation-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-4eYbCDc6IfgfguNmRc5GT4QMCfOEwj+K3BAraABcbpuCzEQ5nCClsVrPbRLfPnhWbQrFc2/eBglB8wsrNTjVBw==", "dependencies": { - "@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", + "@material/animation": "15.0.0-canary.90291f2e2.0", + "@material/base": "15.0.0-canary.90291f2e2.0", + "@material/feature-targeting": "15.0.0-canary.90291f2e2.0", + "@material/rtl": "15.0.0-canary.90291f2e2.0", + "@material/theme": "15.0.0-canary.90291f2e2.0", "tslib": "^2.1.0" } }, "node_modules/@material/fab": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/fab/-/fab-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-YJuJRdqe57DnJ4qyc04flknuGeN+7Nc9ciFZE6snPn84wD6J1khscb21yRARbALDki18kbfnJNrNbzHkYaEMZg==", "dependencies": { - "@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", + "@material/animation": "15.0.0-canary.90291f2e2.0", + "@material/dom": "15.0.0-canary.90291f2e2.0", + "@material/elevation": "15.0.0-canary.90291f2e2.0", + "@material/feature-targeting": "15.0.0-canary.90291f2e2.0", + "@material/focus-ring": "15.0.0-canary.90291f2e2.0", + "@material/ripple": "15.0.0-canary.90291f2e2.0", + "@material/rtl": "15.0.0-canary.90291f2e2.0", + "@material/shape": "15.0.0-canary.90291f2e2.0", + "@material/theme": "15.0.0-canary.90291f2e2.0", + "@material/tokens": "15.0.0-canary.90291f2e2.0", + "@material/touch-target": "15.0.0-canary.90291f2e2.0", + "@material/typography": "15.0.0-canary.90291f2e2.0", "tslib": "^2.1.0" } }, "node_modules/@material/feature-targeting": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/feature-targeting/-/feature-targeting-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-mjUemPnMLXPooDcPHxxc2uhVUzm7X3NDsE0x0QJnsHDwuejakaRLghVcRDX3x1VmL/p52Eu5HrgW2FryFEiVhQ==", "dependencies": { "tslib": "^2.1.0" } }, "node_modules/@material/floating-label": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/floating-label/-/floating-label-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-dYtgNlXkO0H9Vn76oESZZg1KOa2XIOLhVxhV/qPYrhntET534i7TyajmVk54ncuSSoLPZrbrwrhhR2fUJWxZIg==", "dependencies": { - "@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", + "@material/animation": "15.0.0-canary.90291f2e2.0", + "@material/base": "15.0.0-canary.90291f2e2.0", + "@material/dom": "15.0.0-canary.90291f2e2.0", + "@material/feature-targeting": "15.0.0-canary.90291f2e2.0", + "@material/rtl": "15.0.0-canary.90291f2e2.0", + "@material/theme": "15.0.0-canary.90291f2e2.0", + "@material/typography": "15.0.0-canary.90291f2e2.0", "tslib": "^2.1.0" } }, "node_modules/@material/focus-ring": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/focus-ring/-/focus-ring-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-U7ERDgHi33ZRmqsiO6syFaWsCUGneltX2sYVtLpQnxME7pKFzi22GdUUIslhgHOFjSMBFF9av2Y79VFbyj9BaQ==", "dependencies": { - "@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/dom": "15.0.0-canary.90291f2e2.0", + "@material/feature-targeting": "15.0.0-canary.90291f2e2.0", + "@material/rtl": "15.0.0-canary.90291f2e2.0" } }, "node_modules/@material/form-field": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/form-field/-/form-field-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-KTj+EOobLcPUYy4nR+t0c2Cjvs7jCI4F1w8XuV0bbmSa6Sxh02tMKY2Xa7Lx55A/uUrsUfViMdP60OLzi7HgjQ==", "dependencies": { - "@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", + "@material/base": "15.0.0-canary.90291f2e2.0", + "@material/feature-targeting": "15.0.0-canary.90291f2e2.0", + "@material/ripple": "15.0.0-canary.90291f2e2.0", + "@material/rtl": "15.0.0-canary.90291f2e2.0", + "@material/theme": "15.0.0-canary.90291f2e2.0", + "@material/typography": "15.0.0-canary.90291f2e2.0", "tslib": "^2.1.0" } }, "node_modules/@material/icon-button": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/icon-button/-/icon-button-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-bpqiVPkf/LJEP7iIV5VL9Th0chCIQKTeOuw0mK8HmYucuvqq+k76oPsUcE7mvxRvuKyVh6KJ9fTHAkjse0y7cg==", "dependencies": { - "@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", + "@material/base": "15.0.0-canary.90291f2e2.0", + "@material/density": "15.0.0-canary.90291f2e2.0", + "@material/dom": "15.0.0-canary.90291f2e2.0", + "@material/elevation": "15.0.0-canary.90291f2e2.0", + "@material/feature-targeting": "15.0.0-canary.90291f2e2.0", + "@material/focus-ring": "15.0.0-canary.90291f2e2.0", + "@material/ripple": "15.0.0-canary.90291f2e2.0", + "@material/rtl": "15.0.0-canary.90291f2e2.0", + "@material/theme": "15.0.0-canary.90291f2e2.0", + "@material/touch-target": "15.0.0-canary.90291f2e2.0", "tslib": "^2.1.0" } }, "node_modules/@material/image-list": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/image-list/-/image-list-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-JobM4lWsf9grgbqrLuUtJ5fr8BkG02r9c2oFMl5++dtjtLdXWnUIWbiofna8CeqDFQCKXsCk4Jw8ydSKZvj/3A==", "dependencies": { - "@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", + "@material/feature-targeting": "15.0.0-canary.90291f2e2.0", + "@material/shape": "15.0.0-canary.90291f2e2.0", + "@material/theme": "15.0.0-canary.90291f2e2.0", + "@material/typography": "15.0.0-canary.90291f2e2.0", "tslib": "^2.1.0" } }, "node_modules/@material/layout-grid": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/layout-grid/-/layout-grid-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-f5DSHGf1ka6vHu+8VoTvcU9NkR8fdN2wHmPnITZHQXPVvR6SKoyDzdAf2gacmiTYy69ZFmmJeMcdfNnbcPPUJw==", "dependencies": { "tslib": "^2.1.0" } }, "node_modules/@material/line-ripple": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/line-ripple/-/line-ripple-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-cWpS7l/pFg6cUzL7Lx3ywF6RYF6ESYPkiGlDo9kFERv8lVA2/3m4NF4d9b4kC9h9OWx1b1CaUFRFGD07okgI+g==", "dependencies": { - "@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", + "@material/animation": "15.0.0-canary.90291f2e2.0", + "@material/base": "15.0.0-canary.90291f2e2.0", + "@material/feature-targeting": "15.0.0-canary.90291f2e2.0", + "@material/theme": "15.0.0-canary.90291f2e2.0", "tslib": "^2.1.0" } }, "node_modules/@material/linear-progress": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/linear-progress/-/linear-progress-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-nK5RYn8NFZi/+fznLYoEdY6tSzXiJqOU0tX5by7hStURhP2g/RM5SQaJwyjEmHdorfCUIStgmKsN4rB5aMnxdw==", "dependencies": { - "@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", + "@material/animation": "15.0.0-canary.90291f2e2.0", + "@material/base": "15.0.0-canary.90291f2e2.0", + "@material/dom": "15.0.0-canary.90291f2e2.0", + "@material/feature-targeting": "15.0.0-canary.90291f2e2.0", + "@material/progress-indicator": "15.0.0-canary.90291f2e2.0", + "@material/rtl": "15.0.0-canary.90291f2e2.0", + "@material/theme": "15.0.0-canary.90291f2e2.0", "tslib": "^2.1.0" } }, "node_modules/@material/list": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/list/-/list-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-h2c6G5aPH1bhgl2yBYAW4y86pl+yVl3YdqU0ixemQ5/2uB/t92imUbI+gKH5LzlbuJKenk3rZJ5eaV+t5zTS1A==", "dependencies": { - "@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", + "@material/base": "15.0.0-canary.90291f2e2.0", + "@material/density": "15.0.0-canary.90291f2e2.0", + "@material/dom": "15.0.0-canary.90291f2e2.0", + "@material/feature-targeting": "15.0.0-canary.90291f2e2.0", + "@material/ripple": "15.0.0-canary.90291f2e2.0", + "@material/rtl": "15.0.0-canary.90291f2e2.0", + "@material/shape": "15.0.0-canary.90291f2e2.0", + "@material/theme": "15.0.0-canary.90291f2e2.0", + "@material/tokens": "15.0.0-canary.90291f2e2.0", + "@material/typography": "15.0.0-canary.90291f2e2.0", "tslib": "^2.1.0" } }, "node_modules/@material/menu": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/menu/-/menu-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-yfpBN4Hg59pHMNplh2LIe8t+/qsfyP0iRAtJoCK90SBwX43kv65u22+3vEJmYzm3Ey/m3S3YRFXTFQRQnn9cmA==", "dependencies": { - "@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", + "@material/base": "15.0.0-canary.90291f2e2.0", + "@material/dom": "15.0.0-canary.90291f2e2.0", + "@material/elevation": "15.0.0-canary.90291f2e2.0", + "@material/feature-targeting": "15.0.0-canary.90291f2e2.0", + "@material/list": "15.0.0-canary.90291f2e2.0", + "@material/menu-surface": "15.0.0-canary.90291f2e2.0", + "@material/ripple": "15.0.0-canary.90291f2e2.0", + "@material/rtl": "15.0.0-canary.90291f2e2.0", + "@material/shape": "15.0.0-canary.90291f2e2.0", + "@material/theme": "15.0.0-canary.90291f2e2.0", + "@material/tokens": "15.0.0-canary.90291f2e2.0", "tslib": "^2.1.0" } }, "node_modules/@material/menu-surface": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/menu-surface/-/menu-surface-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-AkRpOjFOJi2ROZPvFo1z8ik61eEyJEew8NuvlzCE4S3BX/RNFrYVh4W5ylo030S01ALCS5zhVOeekxa/4eokZA==", "dependencies": { - "@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", + "@material/animation": "15.0.0-canary.90291f2e2.0", + "@material/base": "15.0.0-canary.90291f2e2.0", + "@material/elevation": "15.0.0-canary.90291f2e2.0", + "@material/feature-targeting": "15.0.0-canary.90291f2e2.0", + "@material/rtl": "15.0.0-canary.90291f2e2.0", + "@material/shape": "15.0.0-canary.90291f2e2.0", + "@material/theme": "15.0.0-canary.90291f2e2.0", "tslib": "^2.1.0" } }, "node_modules/@material/notched-outline": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/notched-outline/-/notched-outline-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-4lpoIoFJ8cb++M1iQpZ+8iypUuTruzyBAkOvoaNjk7EftEV+aS3K6XntGNtlUZoB/fFho3mAUVjT19IHFWD03A==", "dependencies": { - "@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", + "@material/base": "15.0.0-canary.90291f2e2.0", + "@material/feature-targeting": "15.0.0-canary.90291f2e2.0", + "@material/floating-label": "15.0.0-canary.90291f2e2.0", + "@material/rtl": "15.0.0-canary.90291f2e2.0", + "@material/shape": "15.0.0-canary.90291f2e2.0", + "@material/theme": "15.0.0-canary.90291f2e2.0", "tslib": "^2.1.0" } }, "node_modules/@material/progress-indicator": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/progress-indicator/-/progress-indicator-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-trQLSstZIA0C64adW/HycycD+PtMfg6iZCIVuTNlZr7PR2Yc1EjuGyA7ts+iXBHZ0TxVshRbDYMwcDogP0rc1w==", "dependencies": { "tslib": "^2.1.0" } }, "node_modules/@material/radio": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/radio/-/radio-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-Ypl4BZ9w1NdbiiEUV3Xw2pb97prMPGEE+5Lm719sVsaFmI4yCKgtsWNEbCbKixborh2ZDZWGCzgMyUQHf3a8xA==", "dependencies": { - "@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", + "@material/animation": "15.0.0-canary.90291f2e2.0", + "@material/base": "15.0.0-canary.90291f2e2.0", + "@material/density": "15.0.0-canary.90291f2e2.0", + "@material/dom": "15.0.0-canary.90291f2e2.0", + "@material/feature-targeting": "15.0.0-canary.90291f2e2.0", + "@material/focus-ring": "15.0.0-canary.90291f2e2.0", + "@material/ripple": "15.0.0-canary.90291f2e2.0", + "@material/theme": "15.0.0-canary.90291f2e2.0", + "@material/touch-target": "15.0.0-canary.90291f2e2.0", "tslib": "^2.1.0" } }, "node_modules/@material/ripple": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/ripple/-/ripple-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-8yCR/V+7SJ9om0cvAOULF/i5+gPQeT+cuPoCZJQRWq9IndfCmQPY3Zmy26reIT/zEyCebAvMG4/WtU4rc+jxyw==", "dependencies": { - "@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/animation": "15.0.0-canary.90291f2e2.0", + "@material/base": "15.0.0-canary.90291f2e2.0", + "@material/dom": "15.0.0-canary.90291f2e2.0", + "@material/feature-targeting": "15.0.0-canary.90291f2e2.0", + "@material/rtl": "15.0.0-canary.90291f2e2.0", + "@material/theme": "15.0.0-canary.90291f2e2.0", "tslib": "^2.1.0" } }, "node_modules/@material/rtl": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/rtl/-/rtl-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-HkUhD8K03BxWVw21WDViWo01Chi22cZ1rmlsdCtggkxdVjtDhTbYm/3XvRnxt4RVpr6KaYQgRXI/52T5RtBUnw==", "dependencies": { - "@material/theme": "15.0.0-canary.3b5b55e31.0", + "@material/theme": "15.0.0-canary.90291f2e2.0", "tslib": "^2.1.0" } }, "node_modules/@material/segmented-button": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/segmented-button/-/segmented-button-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-u1DF+jbysX6wCqt7dDnHgEo2XhNrwkqHq6YsMOFVCoo54PHt3gpwhD89DONqQJKspkdvZuxYHzpqRtV0GIzYDQ==", "dependencies": { - "@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", + "@material/base": "15.0.0-canary.90291f2e2.0", + "@material/elevation": "15.0.0-canary.90291f2e2.0", + "@material/feature-targeting": "15.0.0-canary.90291f2e2.0", + "@material/ripple": "15.0.0-canary.90291f2e2.0", + "@material/theme": "15.0.0-canary.90291f2e2.0", + "@material/touch-target": "15.0.0-canary.90291f2e2.0", + "@material/typography": "15.0.0-canary.90291f2e2.0", "tslib": "^2.1.0" } }, "node_modules/@material/select": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/select/-/select-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-CCaftyi3eIJl2XqBfHbzj8W2jgTMBzSM2+q4WthA+7z0fYQI4JIHQVHO5YKQG5J9MR1VjYQ0Gy0GNotZLAcoOQ==", "dependencies": { - "@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", + "@material/animation": "15.0.0-canary.90291f2e2.0", + "@material/base": "15.0.0-canary.90291f2e2.0", + "@material/density": "15.0.0-canary.90291f2e2.0", + "@material/dom": "15.0.0-canary.90291f2e2.0", + "@material/elevation": "15.0.0-canary.90291f2e2.0", + "@material/feature-targeting": "15.0.0-canary.90291f2e2.0", + "@material/floating-label": "15.0.0-canary.90291f2e2.0", + "@material/line-ripple": "15.0.0-canary.90291f2e2.0", + "@material/list": "15.0.0-canary.90291f2e2.0", + "@material/menu": "15.0.0-canary.90291f2e2.0", + "@material/menu-surface": "15.0.0-canary.90291f2e2.0", + "@material/notched-outline": "15.0.0-canary.90291f2e2.0", + "@material/ripple": "15.0.0-canary.90291f2e2.0", + "@material/rtl": "15.0.0-canary.90291f2e2.0", + "@material/shape": "15.0.0-canary.90291f2e2.0", + "@material/theme": "15.0.0-canary.90291f2e2.0", + "@material/tokens": "15.0.0-canary.90291f2e2.0", + "@material/typography": "15.0.0-canary.90291f2e2.0", "tslib": "^2.1.0" } }, "node_modules/@material/shape": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/shape/-/shape-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-UEB168x8ovLvH4eoBtRnoCT9QvnxB/ZMpOKW1+C+xWisis6Wy9AX0wKT5T6wIpffYYCaBJuhI+ExX2134rAxJw==", "dependencies": { - "@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/feature-targeting": "15.0.0-canary.90291f2e2.0", + "@material/rtl": "15.0.0-canary.90291f2e2.0", + "@material/theme": "15.0.0-canary.90291f2e2.0", "tslib": "^2.1.0" } }, "node_modules/@material/slider": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/slider/-/slider-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-krbdGHcROlvnZ0X7HT0d+PvJummczeShQeWeV/ZezXnQM7bQoy86qfwtX4ai1dIXYkF9qKTFlta2zZezTJyf5g==", "dependencies": { - "@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", + "@material/animation": "15.0.0-canary.90291f2e2.0", + "@material/base": "15.0.0-canary.90291f2e2.0", + "@material/dom": "15.0.0-canary.90291f2e2.0", + "@material/elevation": "15.0.0-canary.90291f2e2.0", + "@material/feature-targeting": "15.0.0-canary.90291f2e2.0", + "@material/ripple": "15.0.0-canary.90291f2e2.0", + "@material/rtl": "15.0.0-canary.90291f2e2.0", + "@material/theme": "15.0.0-canary.90291f2e2.0", + "@material/tokens": "15.0.0-canary.90291f2e2.0", + "@material/typography": "15.0.0-canary.90291f2e2.0", "tslib": "^2.1.0" } }, "node_modules/@material/snackbar": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/snackbar/-/snackbar-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-f1+HaSaAkALtQqEr6WMUqfwOsJr5nOUjP15GA+sTs9SD7yzwqMeWsVriBdWXVRe0zNgew6sfBM+cLjg2w4VAOQ==", "dependencies": { - "@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", + "@material/animation": "15.0.0-canary.90291f2e2.0", + "@material/base": "15.0.0-canary.90291f2e2.0", + "@material/button": "15.0.0-canary.90291f2e2.0", + "@material/dom": "15.0.0-canary.90291f2e2.0", + "@material/elevation": "15.0.0-canary.90291f2e2.0", + "@material/feature-targeting": "15.0.0-canary.90291f2e2.0", + "@material/icon-button": "15.0.0-canary.90291f2e2.0", + "@material/ripple": "15.0.0-canary.90291f2e2.0", + "@material/rtl": "15.0.0-canary.90291f2e2.0", + "@material/shape": "15.0.0-canary.90291f2e2.0", + "@material/theme": "15.0.0-canary.90291f2e2.0", + "@material/tokens": "15.0.0-canary.90291f2e2.0", + "@material/typography": "15.0.0-canary.90291f2e2.0", "tslib": "^2.1.0" } }, "node_modules/@material/switch": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/switch/-/switch-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-94/+Zp2VjlLVJXY7u8VHPcJMHPRVNAwHydiGrKvnJ+6LfbLxAcILNBP9RVKqqqOWQeDxB4ApUl+0TV2Lj6mOzA==", "dependencies": { - "@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", + "@material/animation": "15.0.0-canary.90291f2e2.0", + "@material/base": "15.0.0-canary.90291f2e2.0", + "@material/density": "15.0.0-canary.90291f2e2.0", + "@material/dom": "15.0.0-canary.90291f2e2.0", + "@material/elevation": "15.0.0-canary.90291f2e2.0", + "@material/feature-targeting": "15.0.0-canary.90291f2e2.0", + "@material/focus-ring": "15.0.0-canary.90291f2e2.0", + "@material/ripple": "15.0.0-canary.90291f2e2.0", + "@material/rtl": "15.0.0-canary.90291f2e2.0", + "@material/shape": "15.0.0-canary.90291f2e2.0", + "@material/theme": "15.0.0-canary.90291f2e2.0", + "@material/tokens": "15.0.0-canary.90291f2e2.0", "safevalues": "^0.3.4", "tslib": "^2.1.0" } }, "node_modules/@material/tab": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/tab/-/tab-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-zju6UP038Ddi3XAfliYy58A3OvkQ+zSlOdNOd5l82oMArLYEFi3t51QTjKVjV1wokr6ZQ3Chs4kcrgwVTElYtg==", "dependencies": { - "@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", + "@material/base": "15.0.0-canary.90291f2e2.0", + "@material/elevation": "15.0.0-canary.90291f2e2.0", + "@material/feature-targeting": "15.0.0-canary.90291f2e2.0", + "@material/focus-ring": "15.0.0-canary.90291f2e2.0", + "@material/ripple": "15.0.0-canary.90291f2e2.0", + "@material/rtl": "15.0.0-canary.90291f2e2.0", + "@material/tab-indicator": "15.0.0-canary.90291f2e2.0", + "@material/theme": "15.0.0-canary.90291f2e2.0", + "@material/tokens": "15.0.0-canary.90291f2e2.0", + "@material/typography": "15.0.0-canary.90291f2e2.0", "tslib": "^2.1.0" } }, "node_modules/@material/tab-bar": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/tab-bar/-/tab-bar-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-dTC7oGZg6KuDK2OXO7luJWqshtNY2YgImwZbQ9a1vZZrIGMRHdu+ZtP6RVH2srFVlNIWjzcxfLgNrG+U027RdA==", "dependencies": { - "@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", + "@material/animation": "15.0.0-canary.90291f2e2.0", + "@material/base": "15.0.0-canary.90291f2e2.0", + "@material/density": "15.0.0-canary.90291f2e2.0", + "@material/elevation": "15.0.0-canary.90291f2e2.0", + "@material/feature-targeting": "15.0.0-canary.90291f2e2.0", + "@material/tab": "15.0.0-canary.90291f2e2.0", + "@material/tab-indicator": "15.0.0-canary.90291f2e2.0", + "@material/tab-scroller": "15.0.0-canary.90291f2e2.0", + "@material/theme": "15.0.0-canary.90291f2e2.0", + "@material/tokens": "15.0.0-canary.90291f2e2.0", + "@material/typography": "15.0.0-canary.90291f2e2.0", "tslib": "^2.1.0" } }, "node_modules/@material/tab-indicator": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/tab-indicator/-/tab-indicator-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-GXdFO6rO1crXcj+todijzZQVACW4EC72XwLAl6z69TKBgZrhwCoZ6RgzX6vIXSs+KoZ0eIyQLr+yQQx1JjDd4w==", "dependencies": { - "@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", + "@material/animation": "15.0.0-canary.90291f2e2.0", + "@material/base": "15.0.0-canary.90291f2e2.0", + "@material/feature-targeting": "15.0.0-canary.90291f2e2.0", + "@material/theme": "15.0.0-canary.90291f2e2.0", "tslib": "^2.1.0" } }, "node_modules/@material/tab-scroller": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/tab-scroller/-/tab-scroller-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-R6trOZpkfk54VV0w0NjMMDcZPQgbnARxCoHLrWeSzv5KOMoiDyWji7FFpLc4fynX/F2lNg8xHpEolpugNRW/1g==", "dependencies": { - "@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", + "@material/animation": "15.0.0-canary.90291f2e2.0", + "@material/base": "15.0.0-canary.90291f2e2.0", + "@material/dom": "15.0.0-canary.90291f2e2.0", + "@material/feature-targeting": "15.0.0-canary.90291f2e2.0", + "@material/tab": "15.0.0-canary.90291f2e2.0", "tslib": "^2.1.0" } }, "node_modules/@material/textfield": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/textfield/-/textfield-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-ipxPH8DRh9+cn4MOtAYvGsRLP5RJH/gB/BWh/BiJwjI38Djt4FK4LDHbx7fFo/C8hoj7UNs/BWaSLllyxuWKcg==", "dependencies": { - "@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", + "@material/animation": "15.0.0-canary.90291f2e2.0", + "@material/base": "15.0.0-canary.90291f2e2.0", + "@material/density": "15.0.0-canary.90291f2e2.0", + "@material/dom": "15.0.0-canary.90291f2e2.0", + "@material/feature-targeting": "15.0.0-canary.90291f2e2.0", + "@material/floating-label": "15.0.0-canary.90291f2e2.0", + "@material/line-ripple": "15.0.0-canary.90291f2e2.0", + "@material/notched-outline": "15.0.0-canary.90291f2e2.0", + "@material/ripple": "15.0.0-canary.90291f2e2.0", + "@material/rtl": "15.0.0-canary.90291f2e2.0", + "@material/shape": "15.0.0-canary.90291f2e2.0", + "@material/theme": "15.0.0-canary.90291f2e2.0", + "@material/tokens": "15.0.0-canary.90291f2e2.0", + "@material/typography": "15.0.0-canary.90291f2e2.0", "tslib": "^2.1.0" } }, "node_modules/@material/theme": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/theme/-/theme-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-rDSZ0bPoJothI8nRPQWB4Cyu7DTmc8qIuvFm3OOD4uI/2n+yIFqktS6X+6YF82LeKt4uMTZE+Ce/l51bb8UJGA==", "dependencies": { - "@material/feature-targeting": "15.0.0-canary.3b5b55e31.0", + "@material/feature-targeting": "15.0.0-canary.90291f2e2.0", "tslib": "^2.1.0" } }, "node_modules/@material/tokens": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/tokens/-/tokens-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-ZTis8UeSRrm/4iQ6BujtcTf1J2bs2H+SAEnugtZSQiX8pyf90gQvylEoTuMPdUs1+YJ273cn04ipHdkq3OHaew==", "dependencies": { - "@material/elevation": "15.0.0-canary.3b5b55e31.0" + "@material/elevation": "15.0.0-canary.90291f2e2.0" } }, "node_modules/@material/tooltip": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/tooltip/-/tooltip-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-H3XsrctgRriNwt++NN+Zy6/JhyRznWo2pXiTFnOlaYwHOiGIFCNZR0A/0vf/3Kpf0GYhTfkJEFJMosUSZidSDg==", "dependencies": { - "@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", + "@material/animation": "15.0.0-canary.90291f2e2.0", + "@material/base": "15.0.0-canary.90291f2e2.0", + "@material/button": "15.0.0-canary.90291f2e2.0", + "@material/dom": "15.0.0-canary.90291f2e2.0", + "@material/elevation": "15.0.0-canary.90291f2e2.0", + "@material/feature-targeting": "15.0.0-canary.90291f2e2.0", + "@material/rtl": "15.0.0-canary.90291f2e2.0", + "@material/shape": "15.0.0-canary.90291f2e2.0", + "@material/theme": "15.0.0-canary.90291f2e2.0", + "@material/tokens": "15.0.0-canary.90291f2e2.0", + "@material/typography": "15.0.0-canary.90291f2e2.0", "safevalues": "^0.3.4", "tslib": "^2.1.0" } }, "node_modules/@material/top-app-bar": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/top-app-bar/-/top-app-bar-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-ZiJjK4WpIsE0MZTWokP9r4C9/oDqzUhKRn3ef2WCeJEIU3Vjg4t0xBTnST2vIrcBGw1s7WP1gfaxb3DSXSxzpw==", "dependencies": { - "@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", + "@material/animation": "15.0.0-canary.90291f2e2.0", + "@material/base": "15.0.0-canary.90291f2e2.0", + "@material/elevation": "15.0.0-canary.90291f2e2.0", + "@material/ripple": "15.0.0-canary.90291f2e2.0", + "@material/rtl": "15.0.0-canary.90291f2e2.0", + "@material/shape": "15.0.0-canary.90291f2e2.0", + "@material/theme": "15.0.0-canary.90291f2e2.0", + "@material/typography": "15.0.0-canary.90291f2e2.0", "tslib": "^2.1.0" } }, "node_modules/@material/touch-target": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/touch-target/-/touch-target-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-IpRFf4umZ4ZNxrP+qJkRY9syh7TFZmU4c7EbAlANAJ0/8rlkEo7WJiqa9P1p4nFaT4eMo4n5g+qRI0Dkb9zW5g==", "dependencies": { - "@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", + "@material/base": "15.0.0-canary.90291f2e2.0", + "@material/feature-targeting": "15.0.0-canary.90291f2e2.0", + "@material/rtl": "15.0.0-canary.90291f2e2.0", + "@material/theme": "15.0.0-canary.90291f2e2.0", "tslib": "^2.1.0" } }, "node_modules/@material/typography": { - "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==", + "version": "15.0.0-canary.90291f2e2.0", + "resolved": "https://registry.npmjs.org/@material/typography/-/typography-15.0.0-canary.90291f2e2.0.tgz", + "integrity": "sha512-tv1HWkJYi5T0470k8vbBb+nefdPgsaIO04ocWMf7luvmfE+MZIaR13RxdupLJ4k5otrdydL3/wEaCNhQ+Ipnvw==", "dependencies": { - "@material/feature-targeting": "15.0.0-canary.3b5b55e31.0", - "@material/theme": "15.0.0-canary.3b5b55e31.0", + "@material/feature-targeting": "15.0.0-canary.90291f2e2.0", + "@material/theme": "15.0.0-canary.90291f2e2.0", "tslib": "^2.1.0" } }, "node_modules/@ngtools/webpack": { - "version": "16.0.1", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-16.0.1.tgz", - "integrity": "sha512-CZHFPMiJuOe241kO1VSSPOQ5Z9hWWkY7eSs3hnS50Ntgd4YzlHAydqexmEFpXD2YLOFjdbNETCyJ2BQTM4Kwtw==", + "version": "16.1.1", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-16.1.1.tgz", + "integrity": "sha512-ItW8Hhokk4bQuV8qMpPeNCj0f3LDpddJpd5DwryKb0sSNacGlVff/0nCiKjJFPoCmMSg6ivpkZfqbIyL9RGYXw==", "dev": true, "engines": { "node": "^16.14.0 || >=18.10.0", @@ -4101,8 +3818,8 @@ "yarn": ">= 1.13.0" }, "peerDependencies": { - "@angular/compiler-cli": "^16.0.0", - "typescript": ">=4.9.3 <5.1", + "@angular/compiler-cli": "^16.1.0", + "typescript": ">=4.9.3 <5.2", "webpack": "^5.54.0" } }, @@ -4166,9 +3883,9 @@ } }, "node_modules/@npmcli/git": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-4.0.4.tgz", - "integrity": "sha512-5yZghx+u5M47LghaybLCkdSyFzV/w4OuH12d96HO389Ik9CDsLaDZJVynSGGVJOLn6gy/k7Dz5XYcplM3uxXRg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-4.1.0.tgz", + "integrity": "sha512-9hwoB3gStVfa0N31ymBmrX+GuDGdVA/QWShZVqE0HK2Af+7QGGrCTbZia/SW0ImUTjTne7SP91qxDmtXvDHRPQ==", "dev": true, "dependencies": { "@npmcli/promise-spawn": "^6.0.0", @@ -4224,32 +3941,6 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/@npmcli/move-file": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-2.0.1.tgz", - "integrity": "sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==", - "deprecated": "This functionality has been moved to @npmcli/fs", - "dev": true, - "dependencies": { - "mkdirp": "^1.0.4", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/@npmcli/move-file/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@npmcli/node-gyp": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-3.0.0.tgz", @@ -4388,22 +4079,6 @@ "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", @@ -4420,118 +4095,6 @@ "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", @@ -4615,13 +4178,13 @@ "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" }, "node_modules/@schematics/angular": { - "version": "16.0.1", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-16.0.1.tgz", - "integrity": "sha512-MNgH/iB3WWxMLFVHJjtXCHZ8YHtfx2e3mX2Ds5P43OTgSnTk6tHabqvwxJ4wzjoyoPUyXWLhHt0diCmVtDTNeQ==", + "version": "16.1.1", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-16.1.1.tgz", + "integrity": "sha512-mJo7FxH3dekG7m4hHW5PyWbiCUaU+DSW93j+cikEksda+Qt6NaEX0hM0W3DjH7O+BnEg6dbAEd2GDSN/0XQghw==", "dev": true, "dependencies": { - "@angular-devkit/core": "16.0.1", - "@angular-devkit/schematics": "16.0.1", + "@angular-devkit/core": "16.1.1", + "@angular-devkit/schematics": "16.1.1", "jsonc-parser": "3.2.0" }, "engines": { @@ -4639,6 +4202,20 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, + "node_modules/@sigstore/tuf": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@sigstore/tuf/-/tuf-1.0.0.tgz", + "integrity": "sha512-bLzi9GeZgMCvjJeLUIfs8LJYCxrPRA8IXQkzUtaFKKVPTz0mucRyqFcV2U20yg9K+kYAD0YSitzGfRZCFLjdHQ==", + "dev": true, + "dependencies": { + "@sigstore/protobuf-specs": "^0.1.0", + "make-fetch-happen": "^11.0.1", + "tuf-js": "^1.1.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/@socket.io/component-emitter": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", @@ -4654,34 +4231,6 @@ "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", @@ -4714,9 +4263,9 @@ } }, "node_modules/@tufjs/models/node_modules/minimatch": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.0.tgz", - "integrity": "sha512-0jJj8AvgKqWN05mrwuqi8QYKx1WmYSUoKSxu5Qhs9prezTz10sxAHGNZe9J9cqIJzta8DWsleh2KaVaLl6Ru2w==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz", + "integrity": "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -4850,6 +4399,12 @@ "integrity": "sha512-pYVNNJ+winC4aek+lZp93sIKxnXt5qMkuKmaqS3WGuTq0Bw1ZDYNBgzG5kkdtwcv+GmYJGo3yEg6z2cKKAiEdw==", "dev": true }, + "node_modules/@types/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-/K3ds8TRAfBvi5vfjuz8y6+GiAYBZ0x4tXv1Av6CWBWn0IlADc+ZX9pMq7oU0fNQPnBwIZl3rmeLp6SBApbxSQ==", + "dev": true + }, "node_modules/@types/http-proxy": { "version": "1.17.11", "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.11.tgz", @@ -4860,9 +4415,9 @@ } }, "node_modules/@types/jasmine": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-4.3.1.tgz", - "integrity": "sha512-Vu8l+UGcshYmV1VWwULgnV/2RDbBaO6i2Ptx7nd//oJPIZGhoI1YLST4VKagD2Pq/Bc2/7zvtvhM7F3p4SN7kQ==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-4.3.4.tgz", + "integrity": "sha512-DsJbnxCdjmhRP7dXwjD6JcPc+z7V/4mG3VA1cEFec/+R343TaNPnZ9eJzMkjR4T1BYkjkDIUsPDybkDC0qLrvA==", "dev": true }, "node_modules/@types/jasminewd2": { @@ -4905,6 +4460,12 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.9.tgz", "integrity": "sha512-IeB32oIV4oGArLrd7znD2rkHQ6EDCM+2Sr76dJnrHwv9OHBTTM6nuDLK9bmikXzPa0ZlWMWtRGo/Uw4mrzQedA==" }, + "node_modules/@types/opentype.js": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@types/opentype.js/-/opentype.js-1.3.4.tgz", + "integrity": "sha512-6fbXi67I07ugNM+FExwJnfuui2hD7hraD6nqjr3UnqsbBpxSkrtmO6tBubPdNAjqRT9TVkquVkNS9IkgTtq6/w==", + "dev": true + }, "node_modules/@types/q": { "version": "0.0.32", "resolved": "https://registry.npmjs.org/@types/q/-/q-0.0.32.tgz", @@ -4969,11 +4530,12 @@ } }, "node_modules/@types/serve-static": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.1.tgz", - "integrity": "sha512-NUo5XNiAdULrJENtJXZZ3fHtfMolzZwczzBbnAeBbqBwG+LaG6YaJtuwzwGSQZ2wsCrxjEhNNjAkKigy3n8teQ==", + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.2.tgz", + "integrity": "sha512-J2LqtvFYCzaj8pVYKw8klQXrLLk7TBZmQ4ShlcdkELFKGwGMfevMLneMMRkMgZxotOD9wg497LpC7O8PcvAmfw==", "dev": true, "dependencies": { + "@types/http-errors": "*", "@types/mime": "*", "@types/node": "*" } @@ -5002,24 +4564,24 @@ "dev": true }, "node_modules/@types/ws": { - "version": "8.5.4", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.4.tgz", - "integrity": "sha512-zdQDHKUgcX/zBc4GrwsE/7dVdAD8JR4EuiAXiiUhhfyIJXXb2+PrGshFyeXWQPMmmZ2XxgaqclgpIC7eTXc1mg==", + "version": "8.5.5", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.5.tgz", + "integrity": "sha512-lwhs8hktwxSjf9UaZ9tG5M03PGogvFaH8gUgLNbN9HKIg0dvv6q+gkSuJ8HN4/VbyxkuLzCjlN7GquQ0gUJfIg==", "dev": true, "dependencies": { "@types/node": "*" } }, "node_modules/@typescript-eslint/eslint-plugin": { - "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==", + "version": "5.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.60.0.tgz", + "integrity": "sha512-78B+anHLF1TI8Jn/cD0Q00TBYdMgjdOn980JfAVa9yw5sop8nyTfVOQAv6LWywkOGLclDBtv5z3oxN4w7jxyNg==", "dev": true, "dependencies": { "@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", + "@typescript-eslint/scope-manager": "5.60.0", + "@typescript-eslint/type-utils": "5.60.0", + "@typescript-eslint/utils": "5.60.0", "debug": "^4.3.4", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", @@ -5044,14 +4606,31 @@ } } }, - "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==", + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { + "version": "5.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.60.0.tgz", + "integrity": "sha512-hakuzcxPwXi2ihf9WQu1BbRj1e/Pd8ZZwVTG9kfbxAMZstKz8/9OoexIwnmLzShtsdap5U/CoQGRCWlSuPbYxQ==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "5.59.5", - "@typescript-eslint/utils": "5.59.5", + "@typescript-eslint/types": "5.60.0", + "@typescript-eslint/visitor-keys": "5.60.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/eslint-plugin/node_modules/@typescript-eslint/type-utils": { + "version": "5.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.60.0.tgz", + "integrity": "sha512-X7NsRQddORMYRFH7FWo6sA9Y/zbJ8s1x1RIAtnlj6YprbToTiQnM6vxcMu7iYhdunmoC0rUWlca13D5DVHkK2g==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "5.60.0", + "@typescript-eslint/utils": "5.60.0", "debug": "^4.3.4", "tsutils": "^3.21.0" }, @@ -5071,18 +4650,58 @@ } } }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { + "version": "5.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.60.0.tgz", + "integrity": "sha512-ascOuoCpNZBccFVNJRSC6rPq4EmJ2NkuoKnd6LDNyAQmdDnziAtxbCGWCbefG1CNzmDvd05zO36AmB7H8RzKPA==", + "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/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": { + "version": "5.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.60.0.tgz", + "integrity": "sha512-R43thAuwarC99SnvrBmh26tc7F6sPa2B3evkXp/8q954kYL6Ro56AwASYWtEEi+4j09GbiNAHqYwNNZuNlARGQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.60.0", + "@typescript-eslint/visitor-keys": "5.60.0", + "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/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==", + "version": "5.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.60.0.tgz", + "integrity": "sha512-ba51uMqDtfLQ5+xHtwlO84vkdjrqNzOnqrnwbMHMRY8Tqeme8C2Q8Fc7LajfGR+e3/4LoYiWXUM6BpIIbHJ4hQ==", "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", + "@typescript-eslint/scope-manager": "5.60.0", + "@typescript-eslint/types": "5.60.0", + "@typescript-eslint/typescript-estree": "5.60.0", "eslint-scope": "^5.1.1", "semver": "^7.3.7" }, @@ -5097,6 +4716,23 @@ "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { + "version": "5.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.60.0.tgz", + "integrity": "sha512-wm9Uz71SbCyhUKgcaPRauBdTegUyY/ZWl8gLwD/i/ybJqscrrdVSFImpvUz16BLPChIeKBK5Fa9s6KDQjsjyWw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.60.0", + "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/eslint-plugin/node_modules/eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", @@ -5688,16 +5324,6 @@ "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", @@ -5940,13 +5566,6 @@ "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", @@ -6167,13 +5786,13 @@ } }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz", - "integrity": "sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==", + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.3.tgz", + "integrity": "sha512-bM3gHc337Dta490gg+/AseNB9L4YLHxq1nGKZZSHbhXv4aTYU2MD2cjza1Ru4S6975YLTaL1K8uJf6ukJhhmtw==", "dev": true, "dependencies": { "@babel/compat-data": "^7.17.7", - "@babel/helper-define-polyfill-provider": "^0.3.3", + "@babel/helper-define-polyfill-provider": "^0.4.0", "semver": "^6.1.1" }, "peerDependencies": { @@ -6190,25 +5809,25 @@ } }, "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz", - "integrity": "sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==", + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.1.tgz", + "integrity": "sha512-ikFrZITKg1xH6pLND8zT14UPgjKHiGLqex7rGEZCH2EvhsneJaJPemmpQaIZV5AL03II+lXylw3UmddDK8RU5Q==", "dev": true, "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.3.3", - "core-js-compat": "^3.25.1" + "@babel/helper-define-polyfill-provider": "^0.4.0", + "core-js-compat": "^3.30.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz", - "integrity": "sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.0.tgz", + "integrity": "sha512-hDJtKjMLVa7Z+LwnTCxoDLQj6wdc+B8dun7ayF2fYieI6OzfuvcLMB32ihJZ4UhCBwNYGl5bg/x/P9cMdnkc2g==", "dev": true, "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.3.3" + "@babel/helper-define-polyfill-provider": "^0.4.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" @@ -6539,9 +6158,9 @@ } }, "node_modules/cacache": { - "version": "17.0.6", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-17.0.6.tgz", - "integrity": "sha512-ixcYmEBExFa/+ajIPjcwypxL97CjJyOsH9A/W+4qgEPIpJvKlC+HmVY8nkIck6n3PwUTdgq9c489niJGwl+5Cw==", + "version": "17.1.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-17.1.3.tgz", + "integrity": "sha512-jAdjGxmPxZh0IipMdR7fK/4sDSrHMLUV0+GvVUsjwyGNKHsh79kW/otg+GkbXwl6Uzvy9wsvHOX4nUoWldeZMg==", "dev": true, "dependencies": { "@npmcli/fs": "^3.1.0", @@ -6553,7 +6172,6 @@ "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "p-map": "^4.0.0", - "promise-inflight": "^1.0.1", "ssri": "^10.0.0", "tar": "^6.1.11", "unique-filename": "^3.0.0" @@ -6562,37 +6180,6 @@ "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", @@ -6602,21 +6189,6 @@ "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", @@ -7214,9 +6786,9 @@ } }, "node_modules/core-js-compat": { - "version": "3.30.2", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.30.2.tgz", - "integrity": "sha512-nriW1nuJjUgvkEjIot1Spwakz52V9YkYHZAQG6A1eCgC8AA1p0zngrQEP9R0+V6hji5XilWKG1Bd0YRppmGimA==", + "version": "3.31.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.31.0.tgz", + "integrity": "sha512-hM7YCu1cU6Opx7MXNu0NuumM0ezNeAeRKadixyiQELWY3vT3De9S4J5ZBMraWV2vZnrE1Cirl0GtFtDtMUXzPw==", "dev": true, "dependencies": { "browserslist": "^4.21.5" @@ -7245,9 +6817,9 @@ } }, "node_modules/cosmiconfig": { - "version": "8.1.3", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.1.3.tgz", - "integrity": "sha512-/UkO2JKI18b5jVMJUp0lvKFMpa/Gye+ZgZjKD+DGEN9y7NRcf/nK1A0sp67ONmKtnDCNMS44E6jrk0Yc3bDuUw==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.2.0.tgz", + "integrity": "sha512-3rTMnFJA1tCOPwRxtgF4wd7Ab2qvDbL8jX+3smjIbS4HlZBagTlpERbdN7iAbWlrfxE3M8c27kTwTawQ7st+OQ==", "dev": true, "dependencies": { "import-fresh": "^3.2.1", @@ -7262,22 +6834,6 @@ "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", @@ -7296,24 +6852,18 @@ "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", - "integrity": "sha512-JwjgmO6i3y6RWtLYmXwO5jMd+maZt8Tnfu7VVISmEWyQqfLpB8soBswf8/2bu6SBXxtKA68Al3c+qIG1ApT68A==", + "version": "0.0.19", + "resolved": "https://registry.npmjs.org/critters/-/critters-0.0.19.tgz", + "integrity": "sha512-Fm4ZAXsG0VzWy1U30rP4qxbaWGSsqXDgSupJW1OUJGDAs0KWC+j37v7p5a2kZ9BPJvhRzWm3be+Hc9WvQOBUOw==", "dev": true, "dependencies": { "chalk": "^4.1.0", - "css-select": "^4.2.0", - "parse5": "^6.0.1", - "parse5-htmlparser2-tree-adapter": "^6.0.1", - "postcss": "^8.3.7", + "css-select": "^5.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.2", + "htmlparser2": "^8.0.2", + "postcss": "^8.4.23", "pretty-bytes": "^5.3.0" } }, @@ -7375,12 +6925,6 @@ "node": ">=8" } }, - "node_modules/critters/node_modules/parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", - "dev": true - }, "node_modules/critters/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -7408,15 +6952,15 @@ } }, "node_modules/css-loader": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.7.3.tgz", - "integrity": "sha512-qhOH1KlBMnZP8FzRO6YCH9UHXQhVMcEGLyNdb7Hv2cpcmJbW0YrddO+tG1ab5nT41KpHIYGsbeHqxB9xPu1pKQ==", + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.8.1.tgz", + "integrity": "sha512-xDAXtEVGlD0gJ07iclwWVkLoZOpEvAWaSyf6W18S2pOC//K8+qUDIx8IIT3D+HjnmkJPQeesOPv5aiUaJsCM2g==", "dev": true, "dependencies": { "icss-utils": "^5.1.0", - "postcss": "^8.4.19", + "postcss": "^8.4.21", "postcss-modules-extract-imports": "^3.0.0", - "postcss-modules-local-by-default": "^4.0.0", + "postcss-modules-local-by-default": "^4.0.3", "postcss-modules-scope": "^3.0.0", "postcss-modules-values": "^4.0.0", "postcss-value-parser": "^4.2.0", @@ -7434,15 +6978,15 @@ } }, "node_modules/css-select": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", - "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", "dev": true, "dependencies": { "boolbase": "^1.0.0", - "css-what": "^6.0.1", - "domhandler": "^4.3.1", - "domutils": "^2.8.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", "nth-check": "^2.0.1" }, "funding": { @@ -7834,14 +7378,14 @@ } }, "node_modules/dom-serializer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", - "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", "dev": true, "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" }, "funding": { "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" @@ -7860,12 +7404,12 @@ ] }, "node_modules/domhandler": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", - "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", "dev": true, "dependencies": { - "domelementtype": "^2.2.0" + "domelementtype": "^2.3.0" }, "engines": { "node": ">= 4" @@ -7875,14 +7419,14 @@ } }, "node_modules/domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", "dev": true, "dependencies": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" }, "funding": { "url": "https://github.com/fb55/domutils?sponsor=1" @@ -8037,9 +7581,9 @@ } }, "node_modules/enhanced-resolve": { - "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==", + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", + "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", "dev": true, "dependencies": { "graceful-fs": "^4.2.4", @@ -8068,10 +7612,13 @@ "dev": true }, "node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "dev": true, + "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" + }, "funding": { "url": "https://github.com/fb55/entities?sponsor=1" } @@ -8155,9 +7702,9 @@ } }, "node_modules/esbuild": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.18.tgz", - "integrity": "sha512-z1lix43jBs6UKjcZVKOw2xx69ffE2aG0PygLL5qJ9OS/gy0Ewd1gW/PUQIOIQGXBHWNywSc0floSKoMFF8aK2w==", + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.19.tgz", + "integrity": "sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==", "dev": true, "hasInstallScript": true, "bin": { @@ -8167,34 +7714,34 @@ "node": ">=12" }, "optionalDependencies": { - "@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" + "@esbuild/android-arm": "0.17.19", + "@esbuild/android-arm64": "0.17.19", + "@esbuild/android-x64": "0.17.19", + "@esbuild/darwin-arm64": "0.17.19", + "@esbuild/darwin-x64": "0.17.19", + "@esbuild/freebsd-arm64": "0.17.19", + "@esbuild/freebsd-x64": "0.17.19", + "@esbuild/linux-arm": "0.17.19", + "@esbuild/linux-arm64": "0.17.19", + "@esbuild/linux-ia32": "0.17.19", + "@esbuild/linux-loong64": "0.17.19", + "@esbuild/linux-mips64el": "0.17.19", + "@esbuild/linux-ppc64": "0.17.19", + "@esbuild/linux-riscv64": "0.17.19", + "@esbuild/linux-s390x": "0.17.19", + "@esbuild/linux-x64": "0.17.19", + "@esbuild/netbsd-x64": "0.17.19", + "@esbuild/openbsd-x64": "0.17.19", + "@esbuild/sunos-x64": "0.17.19", + "@esbuild/win32-arm64": "0.17.19", + "@esbuild/win32-ia32": "0.17.19", + "@esbuild/win32-x64": "0.17.19" } }, "node_modules/esbuild-wasm": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.17.18.tgz", - "integrity": "sha512-h4m5zVa+KaDuRFIbH9dokMwovvkIjTQJS7/Ry+0Z1paVuS9aIkso2vdA2GmwH9GSvGX6w71WveJ3PfkoLuWaRw==", + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.17.19.tgz", + "integrity": "sha512-X9UQEMJMZXwlGCfqcBmJ1jEa+KrLfd+gCBypO/TSzo5hZvbVwFqpxj1YCuX54ptTF75wxmrgorR4RL40AKtLVg==", "dev": true, "bin": { "esbuild": "bin/esbuild" @@ -8667,6 +8214,12 @@ "node": ">= 0.8.0" } }, + "node_modules/exponential-backoff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz", + "integrity": "sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==", + "dev": true + }, "node_modules/express": { "version": "4.18.2", "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", @@ -9232,9 +8785,9 @@ } }, "node_modules/fs-monkey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz", - "integrity": "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.4.tgz", + "integrity": "sha512-INM/fWAxMICjttnD0DX1rBvinKskj5G1w+oy/pnm9u/tSlnBrzFonJMcalKJ30P8RRsPzKcCG7Q8l0jx5Fh9YQ==", "dev": true }, "node_modules/fs.realpath": { @@ -9354,19 +8907,22 @@ } }, "node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.0.tgz", + "integrity": "sha512-AQ1/SB9HH0yCx1jXAT4vmCbTOPe5RQ+kCurjbel5xSCGhebumUv+GJZfa1rEqor3XIViqwSEmlkZCQD43RWrBg==", "dev": true, "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" + "foreground-child": "^3.1.0", + "jackspeak": "^2.0.3", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2", + "path-scurry": "^1.7.0" + }, + "bin": { + "glob": "dist/cjs/src/bin.js" }, "engines": { - "node": ">=12" + "node": ">=16 || 14 >=14.17" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -9400,15 +8956,18 @@ } }, "node_modules/glob/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz", + "integrity": "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=10" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/globals": { @@ -9732,10 +9291,20 @@ } }, "node_modules/html-entities": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.3.tgz", - "integrity": "sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==", - "dev": true + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.6.tgz", + "integrity": "sha512-9o0+dcpIw2/HxkNuYKxSJUF/MMRZQECK4GnF+oQOmJ83yCVHTWgCH5aOXxK5bozNRmM8wtgryjHD3uloPBDEGw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ] }, "node_modules/html-escaper": { "version": "2.0.2", @@ -9743,6 +9312,25 @@ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true }, + "node_modules/htmlparser2": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", + "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "entities": "^4.4.0" + } + }, "node_modules/http-cache-semantics": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", @@ -9969,9 +9557,9 @@ } }, "node_modules/ignore-walk/node_modules/minimatch": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.0.tgz", - "integrity": "sha512-0jJj8AvgKqWN05mrwuqi8QYKx1WmYSUoKSxu5Qhs9prezTz10sxAHGNZe9J9cqIJzta8DWsleh2KaVaLl6Ru2w==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz", + "integrity": "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -10051,12 +9639,6 @@ "node": ">=8" } }, - "node_modules/infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "dev": true - }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -10074,9 +9656,9 @@ "dev": true }, "node_modules/ini": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/ini/-/ini-4.0.0.tgz", - "integrity": "sha512-t0ikzf5qkSFqRl1e6ejKBe+Tk2bsQd8ivEkcisyGXsku2t8NvXZ1Y3RRz5vxrDgOrTBOi13CvGsVoI5wVpd7xg==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz", + "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==", "dev": true, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" @@ -10199,9 +9781,9 @@ "dev": true }, "node_modules/ipaddr.js": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.0.1.tgz", - "integrity": "sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz", + "integrity": "sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==", "dev": true, "engines": { "node": ">= 10" @@ -10855,9 +10437,9 @@ } }, "node_modules/jackspeak": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.2.0.tgz", - "integrity": "sha512-r5XBrqIJfwRIjRt/Xr5fv9Wh09qyhHfKnYddDlpM+ibRR20qrYActpCAgU6U+d53EOEjzkvxPMVHSlgR7leXrQ==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.2.1.tgz", + "integrity": "sha512-MXbxovZ/Pm42f6cDIDkl3xpwv1AGwObKwfmjs2nQePiy85tP3fatofl3FC1aBsOtP/6fq5SbtgHwWcMsLP+bDw==", "dev": true, "dependencies": { "@isaacs/cliui": "^8.0.2" @@ -11062,6 +10644,15 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/jiti": { + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.18.2.tgz", + "integrity": "sha512-QAdOptna2NYiSSpv0O/BwoHBSmz4YhpzJHyi+fnMRTXFjp7B8i/YG5Z8IfusxB1ufjcD2Sre1F3R+nX3fvy7gg==", + "dev": true, + "bin": { + "jiti": "bin/jiti.js" + } + }, "node_modules/js-sdsl": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.0.tgz", @@ -11795,92 +11386,30 @@ "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", - "integrity": "sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==", + "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", - "cacache": "^16.1.0", - "http-cache-semantics": "^4.1.0", + "cacache": "^17.0.0", + "http-cache-semantics": "^4.1.1", "http-proxy-agent": "^5.0.0", "https-proxy-agent": "^5.0.0", "is-lambda": "^1.0.1", "lru-cache": "^7.7.1", - "minipass": "^3.1.6", - "minipass-collect": "^1.0.2", - "minipass-fetch": "^2.0.3", + "minipass": "^5.0.0", + "minipass-fetch": "^3.0.0", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "negotiator": "^0.6.3", "promise-retry": "^2.0.1", "socks-proxy-agent": "^7.0.0", - "ssri": "^9.0.0" + "ssri": "^10.0.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/make-fetch-happen/node_modules/@npmcli/fs": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.2.tgz", - "integrity": "sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==", - "dev": true, - "dependencies": { - "@gar/promisify": "^1.1.3", - "semver": "^7.3.5" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/make-fetch-happen/node_modules/cacache": { - "version": "16.1.3", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.1.3.tgz", - "integrity": "sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==", - "dev": true, - "dependencies": { - "@npmcli/fs": "^2.1.0", - "@npmcli/move-file": "^2.0.0", - "chownr": "^2.0.0", - "fs-minipass": "^2.1.0", - "glob": "^8.0.1", - "infer-owner": "^1.0.4", - "lru-cache": "^7.7.1", - "minipass": "^3.1.6", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "mkdirp": "^1.0.4", - "p-map": "^4.0.0", - "promise-inflight": "^1.0.1", - "rimraf": "^3.0.2", - "ssri": "^9.0.0", - "tar": "^6.1.11", - "unique-filename": "^2.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/make-fetch-happen/node_modules/fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dev": true, - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, "node_modules/make-fetch-happen/node_modules/lru-cache": { @@ -11892,72 +11421,6 @@ "node": ">=12" } }, - "node_modules/make-fetch-happen/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/make-fetch-happen/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/make-fetch-happen/node_modules/ssri": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-9.0.1.tgz", - "integrity": "sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==", - "dev": true, - "dependencies": { - "minipass": "^3.1.1" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/make-fetch-happen/node_modules/unique-filename": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-2.0.1.tgz", - "integrity": "sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==", - "dev": true, - "dependencies": { - "unique-slug": "^3.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/make-fetch-happen/node_modules/unique-slug": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-3.0.0.tgz", - "integrity": "sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==", - "dev": true, - "dependencies": { - "imurmurhash": "^0.1.4" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/make-fetch-happen/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/material-colors": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/material-colors/-/material-colors-1.2.6.tgz", @@ -11978,12 +11441,12 @@ } }, "node_modules/memfs": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.1.tgz", - "integrity": "sha512-UWbFJKvj5k+nETdteFndTpYxdeTMox/ULeqX5k/dpaQJCCFmj5EeKv3dBcyO2xmkRAx2vppRu5dVG7SOtsGOzA==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", "dev": true, "dependencies": { - "fs-monkey": "^1.0.3" + "fs-monkey": "^1.0.4" }, "engines": { "node": ">= 4.0.0" @@ -12075,9 +11538,9 @@ } }, "node_modules/mini-css-extract-plugin": { - "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==", + "version": "2.7.6", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.6.tgz", + "integrity": "sha512-Qk7HcgaPkGG6eD77mLvZS1nmxlao3j+9PkrT9Uc7HAE1id3F41+DdBRYRYkbyfNRGzm8/YWtzhw7nVPmwhqTQw==", "dev": true, "dependencies": { "schema-utils": "^4.0.0" @@ -12160,40 +11623,22 @@ "dev": true }, "node_modules/minipass-fetch": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.1.2.tgz", - "integrity": "sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==", + "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": "^3.1.6", + "minipass": "^5.0.0", "minipass-sized": "^1.0.3", "minizlib": "^2.1.2" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" }, "optionalDependencies": { "encoding": "^0.1.13" } }, - "node_modules/minipass-fetch/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-fetch/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/minipass-flush": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", @@ -12484,17 +11929,17 @@ "dev": true }, "node_modules/ngx-color": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/ngx-color/-/ngx-color-8.0.3.tgz", - "integrity": "sha512-tuLP+uIoDEu2m0bh711kb2P1M1bh/oIrOn8mJd9mb8xGL2v+OcokcxPmVvWRn0avMG1lXL53CjSlWXGkdV4CDA==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/ngx-color/-/ngx-color-9.0.0.tgz", + "integrity": "sha512-zyAFux+FRI4cACZ7g8DQQsBbNMhqmFkhtUPaxhkiVHhPzWU1iqXP8MqWH6By3guNOCch5oYrYNBWlHToklbdDg==", "dependencies": { - "@ctrl/tinycolor": "^3.4.1", + "@ctrl/tinycolor": "^3.6.0", "material-colors": "^1.2.6", "tslib": "^2.3.0" }, "peerDependencies": { - "@angular/common": ">=14.0.0-0", - "@angular/core": ">=14.0.0-0" + "@angular/common": ">=16.0.0-0", + "@angular/core": ">=16.0.0-0" } }, "node_modules/nice-napi": { @@ -12528,15 +11973,16 @@ } }, "node_modules/node-gyp": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.3.1.tgz", - "integrity": "sha512-4Q16ZCqq3g8awk6UplT7AuxQ35XN4R/yf/+wSAwcBUAjg7l58RTactWaP8fIDTi0FzI7YcVLujwExakZlfWkXg==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.4.0.tgz", + "integrity": "sha512-dMXsYP6gc9rRbejLXmTbVRYjAHw7ppswsKyMxuxJxxOHzluIO1rGp9TOQgjFJ+2MCqcOcQTOPB/8Xwhr+7s4Eg==", "dev": true, "dependencies": { "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", "glob": "^7.1.4", "graceful-fs": "^4.2.6", - "make-fetch-happen": "^10.0.3", + "make-fetch-happen": "^11.0.3", "nopt": "^6.0.0", "npmlog": "^6.0.0", "rimraf": "^3.0.2", @@ -12729,58 +12175,6 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/npm-registry-fetch/node_modules/lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/npm-registry-fetch/node_modules/make-fetch-happen": { - "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", - "cacache": "^17.0.0", - "http-cache-semantics": "^4.1.1", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.0", - "is-lambda": "^1.0.1", - "lru-cache": "^7.7.1", - "minipass": "^5.0.0", - "minipass-fetch": "^3.0.0", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", - "promise-retry": "^2.0.1", - "socks-proxy-agent": "^7.0.0", - "ssri": "^10.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm-registry-fetch/node_modules/minipass-fetch": { - "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": "^5.0.0", - "minipass-sized": "^1.0.3", - "minizlib": "^2.1.2" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - }, - "optionalDependencies": { - "encoding": "^0.1.13" - } - }, "node_modules/npm-run-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", @@ -13192,6 +12586,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/opentype.js": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/opentype.js/-/opentype.js-1.3.4.tgz", + "integrity": "sha512-d2JE9RP/6uagpQAVtJoF0pJJA/fgai89Cc50Yp0EJHk+eLp6QQ7gBoblsnubRULNY132I0J1QKMJ+JTbMqz4sw==", + "dependencies": { + "string.prototype.codepointat": "^0.2.1", + "tiny-inflate": "^1.0.3" + }, + "bin": { + "ot": "bin/ot" + }, + "engines": { + "node": ">= 8.0.0" + } + }, "node_modules/optionator": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", @@ -13382,9 +12791,9 @@ } }, "node_modules/pacote": { - "version": "15.1.3", - "resolved": "https://registry.npmjs.org/pacote/-/pacote-15.1.3.tgz", - "integrity": "sha512-aRts8cZqxiJVDitmAh+3z+FxuO3tLNWEmwDRPEpDDiZJaRz06clP4XX112ynMT5uF0QNoMPajBBHnaStUEPJXA==", + "version": "15.2.0", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-15.2.0.tgz", + "integrity": "sha512-rJVZeIwHTUta23sIZgEIM62WYwbmGbThdbnkt81ravBplQv+HjyroqnLRNH2+sLJHcGZmLRmhPwACqhfTcOmnA==", "dev": true, "dependencies": { "@npmcli/git": "^4.0.0", @@ -13490,33 +12899,6 @@ "url": "https://github.com/inikulin/parse5?sponsor=1" } }, - "node_modules/parse5-html-rewriting-stream/node_modules/entities": { - "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" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/parse5-htmlparser2-tree-adapter": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", - "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", - "dev": true, - "dependencies": { - "parse5": "^6.0.1" - } - }, - "node_modules/parse5-htmlparser2-tree-adapter/node_modules/parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", - "dev": true - }, "node_modules/parse5-sax-parser": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/parse5-sax-parser/-/parse5-sax-parser-7.0.0.tgz", @@ -13529,18 +12911,6 @@ "url": "https://github.com/inikulin/parse5?sponsor=1" } }, - "node_modules/parse5/node_modules/entities": { - "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" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -13589,13 +12959,13 @@ "dev": true }, "node_modules/path-scurry": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.9.1.tgz", - "integrity": "sha512-UgmoiySyjFxP6tscZDgWGEAgsW5ok8W3F5CJDnnH2pozwSTGE6eH7vwTotMwATWA2r5xqdkKdxYPkwlJjAI/3g==", + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.9.2.tgz", + "integrity": "sha512-qSDLy2aGFPm8i4rsbHd4MNyTcrzHFsLQykrtbuGRknZZCBBVXSv2tSCDN2Cg6Rt/GFRw8GoW9y9Ecw5rIPG1sg==", "dev": true, "dependencies": { "lru-cache": "^9.1.1", - "minipass": "^5.0.0 || ^6.0.0" + "minipass": "^5.0.0 || ^6.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -13605,9 +12975,9 @@ } }, "node_modules/path-scurry/node_modules/lru-cache": { - "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==", + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-9.1.2.tgz", + "integrity": "sha512-ERJq3FOzJTxBbFjZ7iDs+NiK4VI9Wz+RdrrAB8dio1oV+YvdPzUEE4QNiT2VD51DkIbCYRUUzCRkssXCHqSnKQ==", "dev": true, "engines": { "node": "14 || >=16.14" @@ -13717,9 +13087,9 @@ } }, "node_modules/postcss": { - "version": "8.4.23", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.23.tgz", - "integrity": "sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA==", + "version": "8.4.24", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.24.tgz", + "integrity": "sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg==", "dev": true, "funding": [ { @@ -13745,13 +13115,13 @@ } }, "node_modules/postcss-loader": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-7.2.4.tgz", - "integrity": "sha512-F88rpxxNspo5hatIc+orYwZDtHFaVFOSIVAx+fBfJC1GmhWbVmPWtmg2gXKE1OxJbneOSGn8PWdIwsZFcruS+w==", + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-7.3.2.tgz", + "integrity": "sha512-c7qDlXErX6n0VT+LUsW+nwefVtTu3ORtVvK8EXuUIDcxo+b/euYqpuHlJAvePb0Af5e8uMjR/13e0lTuYifaig==", "dev": true, "dependencies": { "cosmiconfig": "^8.1.3", - "cosmiconfig-typescript-loader": "^4.3.0", + "jiti": "^1.18.2", "klona": "^2.0.6", "semver": "^7.3.8" }, @@ -13764,17 +13134,7 @@ }, "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": { @@ -13790,9 +13150,9 @@ } }, "node_modules/postcss-modules-local-by-default": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz", - "integrity": "sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.3.tgz", + "integrity": "sha512-2/u2zraspoACtrbFRnTijMiQtb4GW4BvatjaG/bCjYQo8kLTdevCUlwuBHx2sCnSyrI3x3qj4ZK1j5LQBgzmwA==", "dev": true, "dependencies": { "icss-utils": "^5.0.0", @@ -13837,9 +13197,9 @@ } }, "node_modules/postcss-selector-parser": { - "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==", + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz", + "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==", "dev": true, "dependencies": { "cssesc": "^3.0.0", @@ -14484,9 +13844,9 @@ } }, "node_modules/read-package-json": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-6.0.3.tgz", - "integrity": "sha512-4QbpReW4kxFgeBQ0vPAqh2y8sXEB3D4t3jsXbJKIhBiF80KT6XRo45reqwtftju5J6ru1ax06A2Gb/wM1qCOEQ==", + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-6.0.4.tgz", + "integrity": "sha512-AEtWXYfopBj2z5N5PbkAOeNHRPUg5q+Nen7QLxV8M2zJq1ym6/lCz3fYNTCXe19puu2d06jfHhrP7v/S2PtMMw==", "dev": true, "dependencies": { "glob": "^10.2.2", @@ -14520,37 +13880,6 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/read-package-json/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/read-package-json/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/read-package-json/node_modules/json-parse-even-better-errors": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.0.tgz", @@ -14560,21 +13889,6 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/read-package-json/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/readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", @@ -15020,9 +14334,9 @@ "integrity": "sha512-LRneZZRXNgjzwG4bDQdOTSbze3fHm1EAKN/8bePxnlEZiBmkYEDggaHbuvHI9/hoqHbGfsEA7tWS9GhYHZBBsw==" }, "node_modules/sass": { - "version": "1.62.1", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.62.1.tgz", - "integrity": "sha512-NHpxIzN29MXvWiuswfc1W3I0N8SXBd8UR26WntmDlRYf0bSADnwnOjsyMZ3lMezSlArD33Vs3YFhp7dWvL770A==", + "version": "1.63.2", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.63.2.tgz", + "integrity": "sha512-u56TU0AIFqMtauKl/OJ1AeFsXqRHkgO7nCWmHaDwfxDo9GUMSqBA4NEh6GMuh1CYVM7zuROYtZrHzPc2ixK+ww==", "dev": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0", @@ -15037,9 +14351,9 @@ } }, "node_modules/sass-loader": { - "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==", + "version": "13.3.1", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-13.3.1.tgz", + "integrity": "sha512-cBTxmgyVA1nXPvIK4brjJMXOMJ2v2YrQEuHqLw3LylGb3gsR6jAvdjHMcy/+JGTmmIF9SauTrLLR7bsWDMWqgg==", "dev": true, "dependencies": { "klona": "^2.0.6", @@ -15054,7 +14368,7 @@ }, "peerDependencies": { "fibers": ">= 3.1.0", - "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0", + "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0", "sass": "^1.3.0", "sass-embedded": "*", "webpack": "^5.0.0" @@ -15512,12 +14826,13 @@ "dev": true }, "node_modules/sigstore": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-1.5.0.tgz", - "integrity": "sha512-i3nhvdobiPj8XrXNIggjeur6+A5iAQ4f+r1bR5SGitFJBbthy/6c7Fz0h+kY70Wua1FSMdDr/UEhXSVRXNpynw==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-1.6.0.tgz", + "integrity": "sha512-QODKff/qW/TXOZI6V/Clqu74xnInAS6it05mufj4/fSewexLtfEntgLZZcBtUK44CDQyUE5TUXYy1ARYzlfG9g==", "dev": true, "dependencies": { "@sigstore/protobuf-specs": "^0.1.0", + "@sigstore/tuf": "^1.0.0", "make-fetch-happen": "^11.0.1", "tuf-js": "^1.1.3" }, @@ -15528,58 +14843,6 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/sigstore/node_modules/lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/sigstore/node_modules/make-fetch-happen": { - "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", - "cacache": "^17.0.0", - "http-cache-semantics": "^4.1.1", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.0", - "is-lambda": "^1.0.1", - "lru-cache": "^7.7.1", - "minipass": "^5.0.0", - "minipass-fetch": "^3.0.0", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", - "promise-retry": "^2.0.1", - "socks-proxy-agent": "^7.0.0", - "ssri": "^10.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/sigstore/node_modules/minipass-fetch": { - "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": "^5.0.0", - "minipass-sized": "^1.0.3", - "minizlib": "^2.1.2" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - }, - "optionalDependencies": { - "encoding": "^0.1.13" - } - }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -15626,9 +14889,9 @@ } }, "node_modules/socket.io-parser": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.2.tgz", - "integrity": "sha512-DJtziuKypFkMMHCm2uIshOYC7QaylbtzQwiMYDuCKy3OPkjLzu4B2vAhTlqipRHHzrI0NJeBAizTK7X+6m1jVw==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", + "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", "dev": true, "dependencies": { "@socket.io/component-emitter": "~3.1.0", @@ -15965,6 +15228,11 @@ "node": ">=8" } }, + "node_modules/string.prototype.codepointat": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/string.prototype.codepointat/-/string.prototype.codepointat-0.2.1.tgz", + "integrity": "sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg==" + }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -16079,9 +15347,9 @@ } }, "node_modules/tar": { - "version": "6.1.14", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.14.tgz", - "integrity": "sha512-piERznXu0U7/pW7cdSn7hjqySIVTYT6F76icmFk7ptU7dDYlXTm5r9A6K04R2vU3olYgoKeo1Cg3eeu5nhftAw==", + "version": "6.1.15", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.15.tgz", + "integrity": "sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A==", "dev": true, "dependencies": { "chownr": "^2.0.0", @@ -16154,13 +15422,13 @@ "dev": true }, "node_modules/terser": { - "version": "5.17.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.17.1.tgz", - "integrity": "sha512-hVl35zClmpisy6oaoKALOpS0rDYLxRFLHhRuDlEGTKey9qHjS1w9GMORjuwIMt70Wan4lwsLYyWDVnWgF+KUEw==", + "version": "5.17.7", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.17.7.tgz", + "integrity": "sha512-/bi0Zm2C6VAexlGgLlVxA0P2lru/sdLyfCVaRMfKVo9nWxbmz7f/sD8VPybPeSUJaJcwmCJis9pBIhcVcG1QcQ==", "dev": true, "dependencies": { - "@jridgewell/source-map": "^0.3.2", - "acorn": "^8.5.0", + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, @@ -16306,6 +15574,11 @@ "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", "dev": true }, + "node_modules/tiny-inflate": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz", + "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==" + }, "node_modules/tinycolor2": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.6.0.tgz", @@ -16375,50 +15648,6 @@ "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", @@ -16434,9 +15663,9 @@ } }, "node_modules/tslib": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", - "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==" + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", + "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==" }, "node_modules/tslint": { "version": "6.1.3", @@ -16543,71 +15772,19 @@ "dev": true }, "node_modules/tuf-js": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-1.1.6.tgz", - "integrity": "sha512-CXwFVIsXGbVY4vFiWF7TJKWmlKJAT8TWkH4RmiohJRcDJInix++F0dznDmoVbtJNzZ8yLprKUG4YrDIhv3nBMg==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-1.1.7.tgz", + "integrity": "sha512-i3P9Kgw3ytjELUfpuKVDNBJvk4u5bXL6gskv572mcevPbSKCV3zt3djhmlEQ65yERjIbOSncy7U4cQJaB1CBCg==", "dev": true, "dependencies": { "@tufjs/models": "1.0.4", "debug": "^4.3.4", - "make-fetch-happen": "^11.1.0" + "make-fetch-happen": "^11.1.1" }, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/tuf-js/node_modules/lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/tuf-js/node_modules/make-fetch-happen": { - "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", - "cacache": "^17.0.0", - "http-cache-semantics": "^4.1.1", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.0", - "is-lambda": "^1.0.1", - "lru-cache": "^7.7.1", - "minipass": "^5.0.0", - "minipass-fetch": "^3.0.0", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", - "promise-retry": "^2.0.1", - "socks-proxy-agent": "^7.0.0", - "ssri": "^10.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/tuf-js/node_modules/minipass-fetch": { - "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": "^5.0.0", - "minipass-sized": "^1.0.3", - "minizlib": "^2.1.2" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - }, - "optionalDependencies": { - "encoding": "^0.1.13" - } - }, "node_modules/tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -16851,13 +16028,6 @@ "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", @@ -16903,14 +16073,14 @@ } }, "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==", + "version": "4.3.9", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.3.9.tgz", + "integrity": "sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==", "dev": true, "dependencies": { "esbuild": "^0.17.5", - "postcss": "^8.4.21", - "rollup": "^3.20.2" + "postcss": "^8.4.23", + "rollup": "^3.21.0" }, "bin": { "vite": "bin/vite.js" @@ -17139,9 +16309,9 @@ } }, "node_modules/webpack": { - "version": "5.80.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.80.0.tgz", - "integrity": "sha512-OIMiq37XK1rWO8mH9ssfFKZsXg4n6klTEDL7S8/HqbAOBBaiy8ABvXvz0dDCXeEF9gqwxSvVk611zFPjS8hJxA==", + "version": "5.86.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.86.0.tgz", + "integrity": "sha512-3BOvworZ8SO/D4GVP+GoRC3fVeg5MO4vzmq8TJJEkdmopxyazGDxN8ClqN12uzrZW9Tv8EED8v5VSb6Sqyi0pg==", "dev": true, "dependencies": { "@types/eslint-scope": "^3.7.3", @@ -17150,10 +16320,10 @@ "@webassemblyjs/wasm-edit": "^1.11.5", "@webassemblyjs/wasm-parser": "^1.11.5", "acorn": "^8.7.1", - "acorn-import-assertions": "^1.7.6", + "acorn-import-assertions": "^1.9.0", "browserslist": "^4.14.5", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.13.0", + "enhanced-resolve": "^5.14.1", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", @@ -17186,9 +16356,9 @@ } }, "node_modules/webpack-dev-middleware": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-6.0.2.tgz", - "integrity": "sha512-iOddiJzPcQC6lwOIu60vscbGWth8PCRcWRCwoQcTQf9RMoOWBHg5EyzpGdtSmGMrSPd5vHEfFXmVErQEmkRngQ==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-6.1.1.tgz", + "integrity": "sha512-y51HrHaFeeWir0YO4f0g+9GwZawuigzcAdRNon6jErXy/SqV/+O6eaVAzDqE6t3e3NpGeR5CS+cCDaTC+V3yEQ==", "dev": true, "dependencies": { "colorette": "^2.0.10", @@ -17214,9 +16384,9 @@ } }, "node_modules/webpack-dev-server": { - "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==", + "version": "4.15.0", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.0.tgz", + "integrity": "sha512-HmNB5QeSl1KpulTBQ8UT4FPrByYyaLxpJoQ0+s7EvUrMc16m0ZS1sgb1XGqzmgCPk0c9y+aaXxn11tbLzuM7NQ==", "dev": true, "dependencies": { "@types/bonjour": "^3.5.9", @@ -17317,9 +16487,9 @@ } }, "node_modules/webpack-merge": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz", - "integrity": "sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==", + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.9.0.tgz", + "integrity": "sha512-6NbRQw4+Sy50vYNTw7EyOn41OZItPiXB8GNv3INSoe3PSFaHJEz3SHTrYVaRm2LilNGnFUzh0FAwqPEmU/CwDg==", "dev": true, "dependencies": { "clone-deep": "^4.0.1", @@ -17746,16 +16916,6 @@ "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 4e4fb35db..f9f1b262a 100644 --- a/console/package.json +++ b/console/package.json @@ -12,18 +12,18 @@ }, "private": true, "dependencies": { - "@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", + "@angular/animations": "^16.1.2", + "@angular/cdk": "^16.1.2", + "@angular/common": "^16.1.2", + "@angular/compiler": "^16.1.2", + "@angular/core": "^16.1.2", + "@angular/forms": "^16.1.2", + "@angular/material": "^16.1.2", + "@angular/material-moment-adapter": "^16.1.2", + "@angular/platform-browser": "^16.1.2", + "@angular/platform-browser-dynamic": "^16.1.2", + "@angular/router": "^16.1.2", + "@angular/service-worker": "^16.1.2", "@ctrl/ngx-codemirror": "^6.1.0", "@grpc/grpc-js": "^1.8.14", "@ngx-translate/core": "^14.0.0", @@ -41,7 +41,8 @@ "libphonenumber-js": "^1.10.30", "material-design-icons-iconfont": "^6.1.1", "moment": "^2.29.4", - "ngx-color": "^8.0.3", + "opentype.js": "^1.3.4", + "ngx-color": "^9.0.0", "rxjs": "~7.8.0", "tinycolor2": "^1.6.0", "tslib": "^2.4.1", @@ -49,25 +50,26 @@ "zone.js": "~0.13.0" }, "devDependencies": { - "@angular-devkit/build-angular": "^16.0.1", + "@angular-devkit/build-angular": "^16.1.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", + "@angular/cli": "^16.1.1", + "@angular/compiler-cli": "^16.1.2", + "@angular/language-service": "^16.1.2", "@bufbuild/buf": "^1.18.0-1", "@types/file-saver": "^2.0.2", "@types/google-protobuf": "^3.15.3", - "@types/jasmine": "~4.3.0", + "@types/jasmine": "~4.3.3", "@types/jasminewd2": "~2.0.10", "@types/jsonwebtoken": "^9.0.1", "@types/node": "^18.15.11", + "@types/opentype.js": "^1.3.4", "@types/qrcode": "^1.5.0", "@types/uuid": "^9.0.1", - "@typescript-eslint/eslint-plugin": "^5.59.2", + "@typescript-eslint/eslint-plugin": "^5.59.11", "@typescript-eslint/parser": "^5.59.5", "codelyzer": "^6.0.2", "eslint": "^8.39.0", diff --git a/console/src/app/app.module.ts b/console/src/app/app.module.ts index adb60c8af..57138716f 100644 --- a/console/src/app/app.module.ts +++ b/console/src/app/app.module.ts @@ -1,5 +1,6 @@ import { CommonModule, registerLocaleData } from '@angular/common'; import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http'; +import localeBg from '@angular/common/locales/bg'; import localeDe from '@angular/common/locales/de'; import localeEn from '@angular/common/locales/en'; import localeEs from '@angular/common/locales/es'; @@ -80,6 +81,8 @@ registerLocaleData(localePl); i18nIsoCountries.registerLocale(require('i18n-iso-countries/langs/pl.json')); registerLocaleData(localeZh); i18nIsoCountries.registerLocale(require('i18n-iso-countries/langs/zh.json')); +registerLocaleData(localeBg); +i18nIsoCountries.registerLocale(require('i18n-iso-countries/langs/bg.json')); export class WebpackTranslateLoader implements TranslateLoader { getTranslation(lang: string): Observable { diff --git a/console/src/app/directives/back/back.directive.ts b/console/src/app/directives/back/back.directive.ts index b9548f46f..ca6b0a00d 100644 --- a/console/src/app/directives/back/back.directive.ts +++ b/console/src/app/directives/back/back.directive.ts @@ -1,16 +1,33 @@ import { Directive, ElementRef, HostListener, Renderer2 } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { take } from 'rxjs'; import { NavigationService } from 'src/app/services/navigation.service'; @Directive({ selector: '[cnslBack]', }) export class BackDirective { + new: Boolean = false; @HostListener('click') onClick(): void { this.navigation.back(); + // Go back again to avoid create dialog starts again + if (this.new) { + this.navigation.back(); + } } - constructor(private navigation: NavigationService, private elRef: ElementRef, private renderer2: Renderer2) { + constructor( + private navigation: NavigationService, + private elRef: ElementRef, + private renderer2: Renderer2, + private route: ActivatedRoute, + ) { + // Check if a new element was created using a create dialog + this.route.queryParams.pipe(take(1)).subscribe((params) => { + this.new = params['new']; + }); + if (navigation.isBackPossible) { // this.renderer2.removeStyle(this.elRef.nativeElement, 'visibility'); } else { diff --git a/console/src/app/modules/policies/login-texts/login-texts.component.ts b/console/src/app/modules/policies/login-texts/login-texts.component.ts index a37fb71fa..45fd92ec2 100644 --- a/console/src/app/modules/policies/login-texts/login-texts.component.ts +++ b/console/src/app/modules/policies/login-texts/login-texts.component.ts @@ -19,6 +19,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 { supportedLanguages } from 'src/app/utils/language'; import { InfoSectionType } from '../../info-section/info-section.component'; import { WarnDialogComponent } from '../../warn-dialog/warn-dialog.component'; import { PolicyComponentServiceType } from '../policy-component-types.enum'; @@ -109,7 +110,7 @@ export class LoginTextsComponent implements OnInit, OnDestroy { @Input() public serviceType: PolicyComponentServiceType = PolicyComponentServiceType.MGMT; public KeyNamesArray: string[] = KeyNamesArray; - public LOCALES: string[] = ['de', 'en', 'es', 'fr', 'it', 'ja', 'pl', 'zh']; + public LOCALES: string[] = supportedLanguages; private sub: Subscription = new Subscription(); diff --git a/console/src/app/modules/policies/message-texts/message-texts.component.ts b/console/src/app/modules/policies/message-texts/message-texts.component.ts index 405f3732d..8ce9b5a70 100644 --- a/console/src/app/modules/policies/message-texts/message-texts.component.ts +++ b/console/src/app/modules/policies/message-texts/message-texts.component.ts @@ -47,6 +47,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 { supportedLanguages } from 'src/app/utils/language'; import { InfoSectionType } from '../../info-section/info-section.component'; import { WarnDialogComponent } from '../../warn-dialog/warn-dialog.component'; import { PolicyComponentServiceType } from '../policy-component-types.enum'; @@ -441,7 +442,7 @@ export class MessageTextsComponent implements OnInit, OnDestroy { }; public locale: string = 'en'; - public LOCALES: string[] = ['de', 'en', 'es', 'fr', 'it', 'ja', 'pl', 'zh']; + public LOCALES: string[] = supportedLanguages; private sub: Subscription = new Subscription(); public canWrite$: Observable = this.authService.isAllowed([ this.serviceType === PolicyComponentServiceType.ADMIN diff --git a/console/src/app/modules/policies/private-labeling-policy/private-labeling-policy.component.html b/console/src/app/modules/policies/private-labeling-policy/private-labeling-policy.component.html index cffa8034d..6ec47521a 100644 --- a/console/src/app/modules/policies/private-labeling-policy/private-labeling-policy.component.html +++ b/console/src/app/modules/policies/private-labeling-policy/private-labeling-policy.component.html @@ -492,7 +492,9 @@
text_fields - + {{ + fontName + }}
diff --git a/console/src/app/modules/policies/private-labeling-policy/private-labeling-policy.component.scss b/console/src/app/modules/policies/private-labeling-policy/private-labeling-policy.component.scss index 78a2f7e8d..c7d137102 100644 --- a/console/src/app/modules/policies/private-labeling-policy/private-labeling-policy.component.scss +++ b/console/src/app/modules/policies/private-labeling-policy/private-labeling-policy.component.scss @@ -243,8 +243,6 @@ } .font-preview { - height: 70px; - width: 70px; display: flex; align-items: center; justify-content: center; @@ -252,22 +250,17 @@ margin-bottom: 1rem; border: 1px solid map-get($foreground, divider); position: relative; + padding: 1rem 0.5rem 1rem 0.75rem; - .icon { - position: absolute; - top: 50%; - left: 50%; - transform: translateX(-50%) translateY(-50%); + .font-name { + margin-left: 0.5rem; + font-size: 16px; } .dl-btn { z-index: 2; - position: absolute; - right: 0; - top: 0; cursor: pointer; visibility: hidden; - transform: translateX(50%) translateY(-50%); } &:hover { diff --git a/console/src/app/modules/policies/private-labeling-policy/private-labeling-policy.component.ts b/console/src/app/modules/policies/private-labeling-policy/private-labeling-policy.component.ts index 6fb17bc86..6e579352d 100644 --- a/console/src/app/modules/policies/private-labeling-policy/private-labeling-policy.component.ts +++ b/console/src/app/modules/policies/private-labeling-policy/private-labeling-policy.component.ts @@ -31,6 +31,7 @@ import { } from 'src/app/services/theme.service'; import { ToastService } from 'src/app/services/toast.service'; +import * as opentype from 'opentype.js'; import { InfoSectionType } from '../../info-section/info-section.component'; import { WarnDialogComponent } from '../../warn-dialog/warn-dialog.component'; import { PolicyComponentServiceType } from '../policy-component-types.enum'; @@ -88,6 +89,8 @@ export class PrivateLabelingPolicyComponent implements OnInit, OnDestroy { public ColorType: any = ColorType; public AssetType: any = AssetType; + public fontName = ''; + public refreshPreview: EventEmitter = new EventEmitter(); public org!: Org.AsObject; public InfoSectionType: any = InfoSectionType; @@ -180,6 +183,10 @@ export class PrivateLabelingPolicyComponent implements OnInit, OnDestroy { if (file) { const formData = new FormData(); formData.append('file', file); + + this.getFontName(file); + this.previewNewFont(file); + switch (this.serviceType) { case PolicyComponentServiceType.MGMT: return this.handleFontUploadPromise(this.assetService.upload(AssetEndpoint.MGMTFONT, formData, this.org.id)); @@ -199,6 +206,7 @@ export class PrivateLabelingPolicyComponent implements OnInit, OnDestroy { this.getPreviewData().then((data) => { if (data.policy) { this.previewData = data.policy; + this.fontName = ''; } }); }, 1000); @@ -374,6 +382,11 @@ export class PrivateLabelingPolicyComponent implements OnInit, OnDestroy { .then((data) => { if (data.policy) { this.previewData = data.policy; + if (this.previewData?.fontUrl) { + this.fetchFontMetadataAndPreview(this.previewData.fontUrl); + } else { + this.fontName = 'Could not parse font name'; + } this.loading = false; } }) @@ -385,6 +398,11 @@ export class PrivateLabelingPolicyComponent implements OnInit, OnDestroy { .then((data) => { if (data.policy) { this.data = data.policy; + if (this.data?.fontUrl) { + this.fetchFontMetadataAndPreview(this.data?.fontUrl); + } else { + this.fontName = 'Could not parse font name'; + } this.loading = false; } }) @@ -678,6 +696,45 @@ export class PrivateLabelingPolicyComponent implements OnInit, OnDestroy { }); } + private fetchFontMetadataAndPreview(url: string): void { + fetch(url) + .then((res) => res.blob()) + .then((blob) => { + this.getFontName(blob); + this.previewNewFont(blob); + }); + } + + private getFontName(blob: Blob): void { + const reader = new FileReader(); + reader.onload = (e) => { + if (e.target && e.target.result) { + try { + const font = opentype.parse(e.target.result); + this.fontName = font.names.fullName['en']; + } catch (e) { + this.fontName = 'Could not parse font name'; + } + } + }; + reader.readAsArrayBuffer(blob); + } + + private previewNewFont(blob: Blob): void { + const reader = new FileReader(); + + reader.onload = (e) => { + if (e.target) { + let customFont = new FontFace('brandingFont', `url(${e.target.result})`); + // typescript complains that add is not found but + // indeed it is https://developer.mozilla.org/en-US/docs/Web/API/FontFaceSet/add + // @ts-ignore + document.fonts.add(customFont); + } + }; + reader.readAsDataURL(blob); + } + // /** // * defaults to false because urls are distinct anyway // */ diff --git a/console/src/app/pages/actions/action-table/action-table.component.ts b/console/src/app/pages/actions/action-table/action-table.component.ts index 0b3f7a594..f767c098b 100644 --- a/console/src/app/pages/actions/action-table/action-table.component.ts +++ b/console/src/app/pages/actions/action-table/action-table.component.ts @@ -98,6 +98,7 @@ export class ActionTableComponent implements OnInit { const dialogRef = this.dialog.open(AddActionDialogComponent, { data: {}, width: '500px', + disableClose: true, }); dialogRef.afterClosed().subscribe((req: CreateActionRequest) => { @@ -120,6 +121,7 @@ export class ActionTableComponent implements OnInit { action: action, }, width: '500px', + disableClose: true, }); dialogRef.afterClosed().subscribe((req: UpdateActionRequest) => { diff --git a/console/src/app/pages/actions/add-action-dialog/add-action-dialog.component.html b/console/src/app/pages/actions/add-action-dialog/add-action-dialog.component.html index 3cd135799..4fbce57fc 100644 --- a/console/src/app/pages/actions/add-action-dialog/add-action-dialog.component.html +++ b/console/src/app/pages/actions/add-action-dialog/add-action-dialog.component.html @@ -2,27 +2,29 @@ {{ 'FLOWS.DIALOG.UPDATE.TITLE' | translate }}
- - {{ 'FLOWS.NAME' | translate }} - - +
+ + {{ 'FLOWS.NAME' | translate }} + + - + - - {{ 'FLOWS.TIMEOUTINSEC' | translate }} - - + + {{ 'FLOWS.TIMEOUTINSEC' | translate }} + + - {{ 'FLOWS.ALLOWEDTOFAIL' | translate }} + {{ 'FLOWS.ALLOWEDTOFAIL' | translate }} +
diff --git a/internal/command/idp_intent.go b/internal/command/idp_intent.go index 1045b7701..99db0323b 100644 --- a/internal/command/idp_intent.go +++ b/internal/command/idp_intent.go @@ -119,17 +119,16 @@ func (c *Commands) SucceedIDPIntent(ctx context.Context, writeModel *IDPIntentWr if err != nil { return "", err } - cmd, err := idpintent.NewSucceededEvent( + cmd := idpintent.NewSucceededEvent( ctx, &idpintent.NewAggregate(writeModel.AggregateID, writeModel.ResourceOwner).Aggregate, idpInfo, + idpUser.GetID(), + idpUser.GetPreferredUsername(), userID, accessToken, idToken, ) - if err != nil { - return "", err - } err = c.pushAppendAndReduce(ctx, writeModel, cmd) if err != nil { return "", err diff --git a/internal/command/idp_intent_model.go b/internal/command/idp_intent_model.go index cd0cb6e8e..182b06b3d 100644 --- a/internal/command/idp_intent_model.go +++ b/internal/command/idp_intent_model.go @@ -16,6 +16,8 @@ type IDPIntentWriteModel struct { FailureURL *url.URL IDPID string IDPUser []byte + IDPUserID string + IDPUserName string IDPAccessToken *crypto.CryptoValue IDPIDToken string UserID string @@ -72,6 +74,8 @@ func (wm *IDPIntentWriteModel) reduceStartedEvent(e *idpintent.StartedEvent) { func (wm *IDPIntentWriteModel) reduceSucceededEvent(e *idpintent.SucceededEvent) { wm.UserID = e.UserID wm.IDPUser = e.IDPUser + wm.IDPUserID = e.IDPUserID + wm.IDPUserName = e.IDPUserName wm.IDPAccessToken = e.IDPAccessToken wm.IDPIDToken = e.IDPIDToken wm.State = domain.IDPIntentStateSucceeded diff --git a/internal/command/idp_intent_test.go b/internal/command/idp_intent_test.go index a0be850fb..08948a200 100644 --- a/internal/command/idp_intent_test.go +++ b/internal/command/idp_intent_test.go @@ -435,22 +435,21 @@ func TestCommands_SucceedIDPIntent(t *testing.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 - }(), + idpintent.NewSucceededEvent( + context.Background(), + &idpintent.NewAggregate("id", "ro").Aggregate, + []byte(`{"sub":"id","preferred_username":"username"}`), + "id", + "username", + "", + &crypto.CryptoValue{ + CryptoType: crypto.TypeEncryption, + Algorithm: "enc", + KeyID: "id", + Crypted: []byte("accessToken"), + }, + "idToken", + ), ), ), ), @@ -458,18 +457,20 @@ func TestCommands_SucceedIDPIntent(t *testing.T) { args{ ctx: context.Background(), writeModel: NewIDPIntentWriteModel("id", "ro"), - idpSession: &oauth.Session{ + idpSession: &openid.Session{ Tokens: &oidc.Tokens[*oidc.IDTokenClaims]{ Token: &oauth2.Token{ AccessToken: "accessToken", }, + IDToken: "idToken", }, }, - idpUser: &oauth.UserMapper{ - RawInfo: map[string]interface{}{ - "id": "id", + idpUser: openid.NewUser(&oidc.UserInfo{ + Subject: "id", + UserInfoProfile: oidc.UserInfoProfile{ + PreferredUsername: "username", }, - }, + }), }, res{ token: "aWQ", diff --git a/internal/command/main_test.go b/internal/command/main_test.go index 5c7b42d3a..184b0a9b0 100644 --- a/internal/command/main_test.go +++ b/internal/command/main_test.go @@ -46,6 +46,12 @@ func eventstoreExpect(t *testing.T, expects ...expect) *eventstore.Eventstore { return es } +func expectEventstore(expects ...expect) func(*testing.T) *eventstore.Eventstore { + return func(t *testing.T) *eventstore.Eventstore { + return eventstoreExpect(t, expects...) + } +} + func eventPusherToEvents(eventsPushes ...eventstore.Command) []*repository.Event { events := make([]*repository.Event, len(eventsPushes)) for i, event := range eventsPushes { @@ -125,6 +131,18 @@ func expectPushFailed(err error, events []*repository.Event, uniqueConstraints . } } +func expectRandomPush(events []*repository.Event, uniqueConstraints ...*repository.UniqueConstraint) expect { + return func(m *mock.MockRepository) { + m.ExpectRandomPush(events, uniqueConstraints...) + } +} + +func expectRandomPushFailed(err error, events []*repository.Event, uniqueConstraints ...*repository.UniqueConstraint) expect { + return func(m *mock.MockRepository) { + m.ExpectRandomPushFailed(err, events, uniqueConstraints...) + } +} + func expectFilter(events ...*repository.Event) expect { return func(m *mock.MockRepository) { m.ExpectFilterEvents(events...) diff --git a/internal/command/session.go b/internal/command/session.go index 2feac20e0..fb1dd42d0 100644 --- a/internal/command/session.go +++ b/internal/command/session.go @@ -23,8 +23,10 @@ type SessionCommands struct { sessionWriteModel *SessionWriteModel passwordWriteModel *HumanPasswordWriteModel + intentWriteModel *IDPIntentWriteModel eventstore *eventstore.Eventstore userPasswordAlg crypto.HashAlgorithm + intentAlg crypto.EncryptionAlgorithm createToken func(sessionID string) (id string, token string, err error) now func() time.Time } @@ -35,6 +37,7 @@ func (c *Commands) NewSessionCommands(cmds []SessionCommand, session *SessionWri sessionWriteModel: session, eventstore: c.eventstore, userPasswordAlg: c.userPasswordAlg, + intentAlg: c.idpConfigEncryption, createToken: c.sessionTokenCreator, now: time.Now, } @@ -80,6 +83,42 @@ func CheckPassword(password string) SessionCommand { } } +// CheckIntent defines a check for a succeeded intent to be executed for a session update +func CheckIntent(intentID, token string) SessionCommand { + return func(ctx context.Context, cmd *SessionCommands) error { + if cmd.sessionWriteModel.UserID == "" { + return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-Sfw3r", "Errors.User.UserIDMissing") + } + if err := crypto.CheckToken(cmd.intentAlg, token, intentID); err != nil { + return err + } + cmd.intentWriteModel = NewIDPIntentWriteModel(intentID, "") + err := cmd.eventstore.FilterToQueryReducer(ctx, cmd.intentWriteModel) + if err != nil { + return err + } + if cmd.intentWriteModel.State != domain.IDPIntentStateSucceeded { + return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-Df4bw", "Errors.Intent.NotSucceeded") + } + if cmd.intentWriteModel.UserID != "" { + if cmd.intentWriteModel.UserID != cmd.sessionWriteModel.UserID { + return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-O8xk3w", "Errors.Intent.OtherUser") + } + } else { + linkWriteModel := NewUserIDPLinkWriteModel(cmd.sessionWriteModel.UserID, cmd.intentWriteModel.IDPID, cmd.intentWriteModel.IDPUserID, cmd.intentWriteModel.ResourceOwner) + err := cmd.eventstore.FilterToQueryReducer(ctx, linkWriteModel) + if err != nil { + return err + } + if linkWriteModel.State != domain.UserIDPLinkStateActive { + return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-O8xk3w", "Errors.Intent.OtherUser") + } + } + cmd.sessionWriteModel.IntentChecked(ctx, cmd.now()) + return nil + } +} + // Exec will execute the commands specified and returns an error on the first occurrence func (s *SessionCommands) Exec(ctx context.Context) error { for _, cmd := range s.cmds { @@ -118,7 +157,7 @@ func (s *SessionCommands) commands(ctx context.Context) (string, []eventstore.Co return token, s.sessionWriteModel.commands, nil } -func (c *Commands) CreateSession(ctx context.Context, cmds []SessionCommand, metadata map[string][]byte) (set *SessionChanged, err error) { +func (c *Commands) CreateSession(ctx context.Context, cmds []SessionCommand, sessionDomain string, metadata map[string][]byte) (set *SessionChanged, err error) { sessionID, err := c.idGenerator.Next() if err != nil { return nil, err @@ -128,8 +167,8 @@ func (c *Commands) CreateSession(ctx context.Context, cmds []SessionCommand, met if err != nil { return nil, err } + sessionWriteModel.Start(ctx, sessionDomain) cmd := c.NewSessionCommands(cmds, sessionWriteModel) - cmd.sessionWriteModel.Start(ctx) return c.updateSession(ctx, cmd, metadata) } diff --git a/internal/command/session_model.go b/internal/command/session_model.go index 24edbfd2e..aed542697 100644 --- a/internal/command/session_model.go +++ b/internal/command/session_model.go @@ -16,6 +16,7 @@ type PasskeyChallengeModel struct { Challenge string AllowedCrentialIDs [][]byte UserVerification domain.UserVerificationRequirement + RPID string } func (p *PasskeyChallengeModel) WebAuthNLogin(human *domain.Human, credentialAssertionData []byte) (*domain.WebAuthNLogin, error) { @@ -28,6 +29,7 @@ func (p *PasskeyChallengeModel) WebAuthNLogin(human *domain.Human, credentialAss Challenge: p.Challenge, AllowedCredentialIDs: p.AllowedCrentialIDs, UserVerification: p.UserVerification, + RPID: p.RPID, }, nil } @@ -38,8 +40,10 @@ type SessionWriteModel struct { UserID string UserCheckedAt time.Time PasswordCheckedAt time.Time + IntentCheckedAt time.Time PasskeyCheckedAt time.Time Metadata map[string][]byte + Domain string State domain.SessionState PasskeyChallenge *PasskeyChallengeModel @@ -68,6 +72,8 @@ func (wm *SessionWriteModel) Reduce() error { wm.reduceUserChecked(e) case *session.PasswordCheckedEvent: wm.reducePasswordChecked(e) + case *session.IntentCheckedEvent: + wm.reduceIntentChecked(e) case *session.PasskeyChallengedEvent: wm.reducePasskeyChallenged(e) case *session.PasskeyCheckedEvent: @@ -90,6 +96,7 @@ func (wm *SessionWriteModel) Query() *eventstore.SearchQueryBuilder { session.AddedType, session.UserCheckedType, session.PasswordCheckedType, + session.IntentCheckedType, session.PasskeyChallengedType, session.PasskeyCheckedType, session.TokenSetType, @@ -105,6 +112,7 @@ func (wm *SessionWriteModel) Query() *eventstore.SearchQueryBuilder { } func (wm *SessionWriteModel) reduceAdded(e *session.AddedEvent) { + wm.Domain = e.Domain wm.State = domain.SessionStateActive } @@ -117,11 +125,16 @@ func (wm *SessionWriteModel) reducePasswordChecked(e *session.PasswordCheckedEve wm.PasswordCheckedAt = e.CheckedAt } +func (wm *SessionWriteModel) reduceIntentChecked(e *session.IntentCheckedEvent) { + wm.IntentCheckedAt = e.CheckedAt +} + func (wm *SessionWriteModel) reducePasskeyChallenged(e *session.PasskeyChallengedEvent) { wm.PasskeyChallenge = &PasskeyChallengeModel{ Challenge: e.Challenge, AllowedCrentialIDs: e.AllowedCrentialIDs, UserVerification: e.UserVerification, + RPID: wm.Domain, } } @@ -138,8 +151,10 @@ func (wm *SessionWriteModel) reduceTerminate() { wm.State = domain.SessionStateTerminated } -func (wm *SessionWriteModel) Start(ctx context.Context) { - wm.commands = append(wm.commands, session.NewAddedEvent(ctx, wm.aggregate)) +func (wm *SessionWriteModel) Start(ctx context.Context, domain string) { + wm.commands = append(wm.commands, session.NewAddedEvent(ctx, wm.aggregate, domain)) + // set the domain so checks can use it + wm.Domain = domain } func (wm *SessionWriteModel) UserChecked(ctx context.Context, userID string, checkedAt time.Time) error { @@ -153,6 +168,10 @@ func (wm *SessionWriteModel) PasswordChecked(ctx context.Context, checkedAt time wm.commands = append(wm.commands, session.NewPasswordCheckedEvent(ctx, wm.aggregate, checkedAt)) } +func (wm *SessionWriteModel) IntentChecked(ctx context.Context, checkedAt time.Time) { + wm.commands = append(wm.commands, session.NewIntentCheckedEvent(ctx, wm.aggregate, checkedAt)) +} + func (wm *SessionWriteModel) PasskeyChallenged(ctx context.Context, challenge string, allowedCrentialIDs [][]byte, userVerification domain.UserVerificationRequirement) { wm.commands = append(wm.commands, session.NewPasskeyChallengedEvent(ctx, wm.aggregate, challenge, allowedCrentialIDs, userVerification)) } diff --git a/internal/command/session_passkey.go b/internal/command/session_passkey.go index d4664ca2f..6de850b23 100644 --- a/internal/command/session_passkey.go +++ b/internal/command/session_passkey.go @@ -43,7 +43,7 @@ func (c *Commands) CreatePasskeyChallenge(userVerification domain.UserVerificati if err != nil { return err } - webAuthNLogin, err := c.webauthnConfig.BeginLogin(ctx, humanPasskeys.human, userVerification, humanPasskeys.tokens...) + webAuthNLogin, err := c.webauthnConfig.BeginLogin(ctx, humanPasskeys.human, userVerification, cmd.sessionWriteModel.Domain, humanPasskeys.tokens...) if err != nil { return err } diff --git a/internal/command/session_passkeys_test.go b/internal/command/session_passkeys_test.go index fdc324537..a934c83d7 100644 --- a/internal/command/session_passkeys_test.go +++ b/internal/command/session_passkeys_test.go @@ -84,7 +84,7 @@ func TestSessionCommands_getHumanPasskeys(t *testing.T) { expectFilter(eventFromEventPusher( user.NewHumanWebAuthNAddedEvent(eventstore.NewBaseEventForPush( context.Background(), &org.NewAggregate("org1").Aggregate, user.HumanPasswordlessTokenAddedType, - ), "111", "challenge"), + ), "111", "challenge", "rpID"), )), ), sessionWriteModel: &SessionWriteModel{ @@ -112,6 +112,7 @@ func TestSessionCommands_getHumanPasskeys(t *testing.T) { WebAuthNTokenID: "111", State: domain.MFAStateNotReady, Challenge: "challenge", + RPID: "rpID", }}, }, err: nil, diff --git a/internal/command/session_test.go b/internal/command/session_test.go index b9e24b03e..92d19ac24 100644 --- a/internal/command/session_test.go +++ b/internal/command/session_test.go @@ -18,6 +18,7 @@ import ( "github.com/zitadel/zitadel/internal/eventstore" "github.com/zitadel/zitadel/internal/id" "github.com/zitadel/zitadel/internal/id/mock" + "github.com/zitadel/zitadel/internal/repository/idpintent" "github.com/zitadel/zitadel/internal/repository/session" "github.com/zitadel/zitadel/internal/repository/user" ) @@ -146,6 +147,7 @@ func TestCommands_CreateSession(t *testing.T) { type args struct { ctx context.Context checks []SessionCommand + domain string metadata map[string][]byte } type res struct { @@ -193,7 +195,7 @@ func TestCommands_CreateSession(t *testing.T) { expectFilter(), expectPush( eventPusherToEvents( - session.NewAddedEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate), + session.NewAddedEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate, ""), session.NewTokenSetEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate, "tokenID", ), @@ -217,6 +219,39 @@ func TestCommands_CreateSession(t *testing.T) { }, }, }, + { + "empty session with domain", + fields{ + idGenerator: mock.NewIDGeneratorExpectIDs(t, "sessionID"), + eventstore: eventstoreExpect(t, + expectFilter(), + expectPush( + eventPusherToEvents( + session.NewAddedEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate, "domain.tld"), + session.NewTokenSetEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate, + "tokenID", + ), + ), + ), + ), + tokenCreator: func(sessionID string) (string, string, error) { + return "tokenID", + "token", + nil + }, + }, + args{ + ctx: authz.NewMockContext("", "org1", ""), + domain: "domain.tld", + }, + res{ + want: &SessionChanged{ + ObjectDetails: &domain.ObjectDetails{ResourceOwner: "org1"}, + ID: "sessionID", + NewToken: "token", + }, + }, + }, // the rest is tested in the Test_updateSession } for _, tt := range tests { @@ -226,7 +261,7 @@ func TestCommands_CreateSession(t *testing.T) { idGenerator: tt.fields.idGenerator, sessionTokenCreator: tt.fields.tokenCreator, } - got, err := c.CreateSession(tt.args.ctx, tt.args.checks, tt.args.metadata) + got, err := c.CreateSession(tt.args.ctx, tt.args.checks, tt.args.domain, tt.args.metadata) require.ErrorIs(t, err, tt.res.err) assert.Equal(t, tt.res.want, got) }) @@ -275,7 +310,7 @@ func TestCommands_UpdateSession(t *testing.T) { eventstore: eventstoreExpect(t, expectFilter( eventFromEventPusher( - session.NewAddedEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate)), + session.NewAddedEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate, "domain.tld")), eventFromEventPusher( session.NewTokenSetEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate, "tokenID")), @@ -300,7 +335,7 @@ func TestCommands_UpdateSession(t *testing.T) { eventstore: eventstoreExpect(t, expectFilter( eventFromEventPusher( - session.NewAddedEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate)), + session.NewAddedEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate, "domain.tld")), eventFromEventPusher( session.NewTokenSetEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate, "tokenID")), @@ -341,6 +376,19 @@ func TestCommands_UpdateSession(t *testing.T) { } func TestCommands_updateSession(t *testing.T) { + decryption := func(err error) crypto.EncryptionAlgorithm { + mCrypto := crypto.NewMockEncryptionAlgorithm(gomock.NewController(t)) + mCrypto.EXPECT().EncryptionKeyID().Return("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 + } + testNow := time.Now() type fields struct { eventstore *eventstore.Eventstore @@ -484,6 +532,194 @@ func TestCommands_updateSession(t *testing.T) { }, }, }, + { + "set user, intent not successful", + fields{ + eventstore: eventstoreExpect(t), + }, + args{ + ctx: context.Background(), + checks: &SessionCommands{ + sessionWriteModel: NewSessionWriteModel("sessionID", "org1"), + cmds: []SessionCommand{ + CheckUser("userID"), + CheckIntent("intent", "aW50ZW50"), + }, + eventstore: eventstoreExpect(t, + expectFilter( + eventFromEventPusher( + user.NewHumanAddedEvent(context.Background(), &user.NewAggregate("userID", "org1").Aggregate, + "username", "", "", "", "", language.English, domain.GenderUnspecified, "", false), + ), + ), + ), + createToken: func(sessionID string) (string, string, error) { + return "tokenID", + "token", + nil + }, + intentAlg: decryption(nil), + now: func() time.Time { + return testNow + }, + }, + metadata: map[string][]byte{ + "key": []byte("value"), + }, + }, + res{ + err: caos_errs.ThrowPreconditionFailed(nil, "COMMAND-Df4bw", "Errors.Intent.NotSucceeded"), + }, + }, + { + "set user, intent not for user", + fields{ + eventstore: eventstoreExpect(t), + }, + args{ + ctx: context.Background(), + checks: &SessionCommands{ + sessionWriteModel: NewSessionWriteModel("sessionID", "org1"), + cmds: []SessionCommand{ + CheckUser("userID"), + CheckIntent("intent", "aW50ZW50"), + }, + eventstore: eventstoreExpect(t, + expectFilter( + eventFromEventPusher( + user.NewHumanAddedEvent(context.Background(), &user.NewAggregate("userID", "org1").Aggregate, + "username", "", "", "", "", language.English, domain.GenderUnspecified, "", false), + ), + eventFromEventPusher( + idpintent.NewSucceededEvent(context.Background(), &idpintent.NewAggregate("intent", "org1").Aggregate, + nil, + "idpUserID", + "idpUserName", + "userID2", + nil, + "", + ), + ), + ), + ), + createToken: func(sessionID string) (string, string, error) { + return "tokenID", + "token", + nil + }, + intentAlg: decryption(nil), + now: func() time.Time { + return testNow + }, + }, + metadata: map[string][]byte{ + "key": []byte("value"), + }, + }, + res{ + err: caos_errs.ThrowPreconditionFailed(nil, "COMMAND-O8xk3w", "Errors.Intent.OtherUser"), + }, + }, + { + "set user, intent incorrect token", + fields{ + eventstore: eventstoreExpect(t), + }, + args{ + ctx: context.Background(), + checks: &SessionCommands{ + sessionWriteModel: NewSessionWriteModel("sessionID", "org1"), + cmds: []SessionCommand{ + CheckUser("userID"), + CheckIntent("intent2", "aW50ZW50"), + }, + eventstore: eventstoreExpect(t), + createToken: func(sessionID string) (string, string, error) { + return "tokenID", + "token", + nil + }, + intentAlg: decryption(nil), + now: func() time.Time { + return testNow + }, + }, + metadata: map[string][]byte{ + "key": []byte("value"), + }, + }, + res{ + err: caos_errs.ThrowPermissionDenied(nil, "CRYPTO-CRYPTO", "Errors.Intent.InvalidToken"), + }, + }, + { + "set user, intent, metadata and token", + fields{ + eventstore: eventstoreExpect(t, + expectPush( + eventPusherToEvents( + session.NewUserCheckedEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate, + "userID", testNow), + session.NewIntentCheckedEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate, + testNow), + session.NewMetadataSetEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate, + map[string][]byte{"key": []byte("value")}), + session.NewTokenSetEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate, + "tokenID"), + ), + ), + ), + }, + args{ + ctx: context.Background(), + checks: &SessionCommands{ + sessionWriteModel: NewSessionWriteModel("sessionID", "org1"), + cmds: []SessionCommand{ + CheckUser("userID"), + CheckIntent("intent", "aW50ZW50"), + }, + eventstore: eventstoreExpect(t, + expectFilter( + eventFromEventPusher( + user.NewHumanAddedEvent(context.Background(), &user.NewAggregate("userID", "org1").Aggregate, + "username", "", "", "", "", language.English, domain.GenderUnspecified, "", false), + ), + eventFromEventPusher( + idpintent.NewSucceededEvent(context.Background(), &idpintent.NewAggregate("intent", "org1").Aggregate, + nil, + "idpUserID", + "idpUsername", + "userID", + nil, + "", + ), + ), + ), + ), + createToken: func(sessionID string) (string, string, error) { + return "tokenID", + "token", + nil + }, + intentAlg: decryption(nil), + now: func() time.Time { + return testNow + }, + }, + metadata: map[string][]byte{ + "key": []byte("value"), + }, + }, + res{ + want: &SessionChanged{ + ObjectDetails: &domain.ObjectDetails{ + ResourceOwner: "org1", + }, + ID: "sessionID", + NewToken: "token", + }, + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -537,7 +773,7 @@ func TestCommands_TerminateSession(t *testing.T) { eventstore: eventstoreExpect(t, expectFilter( eventFromEventPusher( - session.NewAddedEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate)), + session.NewAddedEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate, "domain.tld")), eventFromEventPusher( session.NewTokenSetEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate, "tokenID")), @@ -562,7 +798,7 @@ func TestCommands_TerminateSession(t *testing.T) { eventstore: eventstoreExpect(t, expectFilter( eventFromEventPusher( - session.NewAddedEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate)), + session.NewAddedEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate, "domain.tld")), eventFromEventPusher( session.NewTokenSetEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate, "tokenID")), @@ -591,7 +827,7 @@ func TestCommands_TerminateSession(t *testing.T) { eventstore: eventstoreExpect(t, expectFilter( eventFromEventPusher( - session.NewAddedEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate)), + session.NewAddedEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate, "domain.tld")), eventFromEventPusher( session.NewTokenSetEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate, "tokenID"), @@ -622,7 +858,7 @@ func TestCommands_TerminateSession(t *testing.T) { eventstore: eventstoreExpect(t, expectFilter( eventFromEventPusher( - session.NewAddedEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate)), + session.NewAddedEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate, "domain.tld")), eventFromEventPusher( session.NewTokenSetEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate, "tokenID"), diff --git a/internal/command/user_converter.go b/internal/command/user_converter.go index 599671e1f..62cee0bed 100644 --- a/internal/command/user_converter.go +++ b/internal/command/user_converter.go @@ -140,6 +140,7 @@ func writeModelToWebAuthN(wm *HumanWebAuthNWriteModel) *domain.WebAuthNToken { SignCount: wm.SignCount, WebAuthNTokenName: wm.WebAuthNTokenName, State: wm.State, + RPID: wm.RPID, } } diff --git a/internal/command/user_human_otp.go b/internal/command/user_human_otp.go index 96db142f7..8bf6f0468 100644 --- a/internal/command/user_human_otp.go +++ b/internal/command/user_human_otp.go @@ -3,12 +3,14 @@ package command import ( "context" + "github.com/pquerna/otp" "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/eventstore/v1/models" "github.com/zitadel/zitadel/internal/repository/user" "github.com/zitadel/zitadel/internal/telemetry/tracing" @@ -43,7 +45,32 @@ func (c *Commands) AddHumanOTP(ctx context.Context, userID, resourceowner string if userID == "" { return nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-5M0sd", "Errors.User.UserIDMissing") } - human, err := c.getHuman(ctx, userID, resourceowner) + prep, err := c.createHumanTOTP(ctx, userID, resourceowner) + if err != nil { + return nil, err + } + _, err = c.eventstore.Push(ctx, prep.cmds...) + if err != nil { + return nil, err + } + return &domain.OTP{ + ObjectRoot: models.ObjectRoot{ + AggregateID: prep.userAgg.ID, + }, + SecretString: prep.key.Secret(), + Url: prep.key.URL(), + }, nil +} + +type preparedTOTP struct { + wm *HumanOTPWriteModel + userAgg *eventstore.Aggregate + key *otp.Key + cmds []eventstore.Command +} + +func (c *Commands) createHumanTOTP(ctx context.Context, userID, resourceOwner string) (*preparedTOTP, error) { + human, err := c.getHuman(ctx, userID, resourceOwner) if err != nil { logging.Log("COMMAND-DAqe1").WithError(err).WithField("traceID", tracing.TraceIDFromCtx(ctx)).Debug("unable to get human for loginname") return nil, caos_errs.ThrowPreconditionFailed(err, "COMMAND-MM9fs", "Errors.User.NotFound") @@ -59,7 +86,7 @@ func (c *Commands) AddHumanOTP(ctx context.Context, userID, resourceowner string return nil, caos_errs.ThrowPreconditionFailed(err, "COMMAND-8ugTs", "Errors.Org.DomainPolicy.NotFound") } - otpWriteModel, err := c.otpWriteModelByID(ctx, userID, resourceowner) + otpWriteModel, err := c.otpWriteModelByID(ctx, userID, resourceOwner) if err != nil { return nil, err } @@ -80,16 +107,13 @@ func (c *Commands) AddHumanOTP(ctx context.Context, userID, resourceowner string if err != nil { return nil, err } - _, err = c.eventstore.Push(ctx, user.NewHumanOTPAddedEvent(ctx, userAgg, secret)) - if err != nil { - return nil, err - } - return &domain.OTP{ - ObjectRoot: models.ObjectRoot{ - AggregateID: human.AggregateID, + return &preparedTOTP{ + wm: otpWriteModel, + userAgg: userAgg, + key: key, + cmds: []eventstore.Command{ + user.NewHumanOTPAddedEvent(ctx, userAgg, secret), }, - SecretString: key.Secret(), - Url: key.URL(), }, nil } diff --git a/internal/command/user_human_otp_test.go b/internal/command/user_human_otp_test.go index c894a63f6..e11f771e6 100644 --- a/internal/command/user_human_otp_test.go +++ b/internal/command/user_human_otp_test.go @@ -2,11 +2,17 @@ package command import ( "context" + "io" "testing" + "time" + "github.com/golang/mock/gomock" + "github.com/pquerna/otp/totp" "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" @@ -231,6 +237,476 @@ func TestCommandSide_AddHumanOTP(t *testing.T) { } } +func TestCommands_createHumanOTP(t *testing.T) { + type fields struct { + eventstore *eventstore.Eventstore + } + type args struct { + ctx context.Context + userID string + resourceOwner string + } + tests := []struct { + name string + fields fields + args args + want bool + wantErr error + }{ + { + name: "user not existing, not found error", + fields: fields{ + eventstore: eventstoreExpect( + t, + expectFilter(), + ), + }, + args: args{ + ctx: context.Background(), + resourceOwner: "org1", + userID: "user1", + }, + wantErr: caos_errs.ThrowPreconditionFailed(nil, "COMMAND-MM9fs", "Errors.User.NotFound"), + }, + { + name: "org not existing, not found error", + fields: fields{ + eventstore: eventstoreExpect( + t, + expectFilter( + eventFromEventPusher( + user.NewHumanAddedEvent(context.Background(), + &user.NewAggregate("user1", "org1").Aggregate, + "username", + "firstname", + "lastname", + "nickname", + "displayname", + language.German, + domain.GenderUnspecified, + "email@test.ch", + true, + ), + ), + ), + expectFilter(), + ), + }, + args: args{ + ctx: context.Background(), + resourceOwner: "org1", + userID: "user1", + }, + wantErr: caos_errs.ThrowPreconditionFailed(nil, "COMMAND-55M9f", "Errors.Org.NotFound"), + }, + { + name: "org iam policy not existing, not found error", + fields: fields{ + eventstore: eventstoreExpect( + t, + expectFilter( + eventFromEventPusher( + user.NewHumanAddedEvent(context.Background(), + &user.NewAggregate("user1", "org1").Aggregate, + "username", + "firstname", + "lastname", + "nickname", + "displayname", + language.German, + domain.GenderUnspecified, + "email@test.ch", + true, + ), + ), + ), + expectFilter( + eventFromEventPusher( + org.NewOrgAddedEvent(context.Background(), + &user.NewAggregate("org1", "org1").Aggregate, + "org", + ), + ), + ), + expectFilter(), + expectFilter(), + ), + }, + args: args{ + ctx: context.Background(), + resourceOwner: "org1", + userID: "user1", + }, + wantErr: caos_errs.ThrowPreconditionFailed(nil, "COMMAND-8ugTs", "Errors.Org.DomainPolicy.NotFound"), + }, + { + name: "otp already exists, already exists error", + fields: fields{ + eventstore: eventstoreExpect( + t, + expectFilter( + eventFromEventPusher( + user.NewHumanAddedEvent(context.Background(), + &user.NewAggregate("user1", "org1").Aggregate, + "username", + "firstname", + "lastname", + "nickname", + "displayname", + language.German, + domain.GenderUnspecified, + "email@test.ch", + true, + ), + ), + ), + expectFilter( + eventFromEventPusher( + org.NewOrgAddedEvent(context.Background(), + &user.NewAggregate("org1", "org1").Aggregate, + "org", + ), + ), + ), + expectFilter( + eventFromEventPusher( + org.NewDomainPolicyAddedEvent(context.Background(), + &org.NewAggregate("org1").Aggregate, + true, + true, + true, + ), + ), + ), + expectFilter( + eventFromEventPusher( + user.NewHumanOTPAddedEvent(context.Background(), + &user.NewAggregate("user1", "org1").Aggregate, + &crypto.CryptoValue{ + CryptoType: crypto.TypeEncryption, + Algorithm: "enc", + KeyID: "id", + Crypted: []byte("a"), + }), + ), + eventFromEventPusher( + user.NewHumanOTPVerifiedEvent(context.Background(), + &user.NewAggregate("user1", "org1").Aggregate, + "agent1")), + ), + ), + }, + args: args{ + ctx: context.Background(), + resourceOwner: "org1", + userID: "user1", + }, + wantErr: caos_errs.ThrowAlreadyExists(nil, "COMMAND-do9se", "Errors.User.MFA.OTP.AlreadyReady"), + }, + { + name: "issuer not in context", + fields: fields{ + eventstore: eventstoreExpect( + t, + expectFilter( + eventFromEventPusher( + user.NewHumanAddedEvent(context.Background(), + &user.NewAggregate("user1", "org1").Aggregate, + "username", + "firstname", + "lastname", + "nickname", + "displayname", + language.German, + domain.GenderUnspecified, + "email@test.ch", + true, + ), + ), + ), + expectFilter( + eventFromEventPusher( + org.NewOrgAddedEvent(context.Background(), + &user.NewAggregate("org1", "org1").Aggregate, + "org", + ), + ), + ), + expectFilter( + eventFromEventPusher( + org.NewDomainPolicyAddedEvent(context.Background(), + &org.NewAggregate("org1").Aggregate, + true, + true, + true, + ), + ), + ), + expectFilter(), + ), + }, + args: args{ + ctx: context.Background(), + resourceOwner: "org1", + userID: "user1", + }, + wantErr: caos_errs.ThrowInternal(nil, "TOTP-ieY3o", "Errors.Internal"), + }, + { + name: "success", + fields: fields{ + eventstore: eventstoreExpect( + t, + expectFilter( + eventFromEventPusher( + user.NewHumanAddedEvent(context.Background(), + &user.NewAggregate("user1", "org1").Aggregate, + "username", + "firstname", + "lastname", + "nickname", + "displayname", + language.German, + domain.GenderUnspecified, + "email@test.ch", + true, + ), + ), + ), + expectFilter( + eventFromEventPusher( + org.NewOrgAddedEvent(context.Background(), + &user.NewAggregate("org1", "org1").Aggregate, + "org", + ), + ), + ), + expectFilter( + eventFromEventPusher( + org.NewDomainPolicyAddedEvent(context.Background(), + &org.NewAggregate("org1").Aggregate, + true, + true, + true, + ), + ), + ), + expectFilter(), + ), + }, + args: args{ + ctx: authz.WithRequestedDomain(context.Background(), "zitadel.com"), + resourceOwner: "org1", + userID: "user1", + }, + want: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := &Commands{ + eventstore: tt.fields.eventstore, + multifactors: domain.MultifactorConfigs{ + OTP: domain.OTPConfig{ + CryptoMFA: crypto.CreateMockEncryptionAlg(gomock.NewController(t)), + }, + }, + } + got, err := c.createHumanTOTP(tt.args.ctx, tt.args.userID, tt.args.resourceOwner) + require.ErrorIs(t, err, tt.wantErr) + if tt.want { + require.NotNil(t, got) + assert.NotNil(t, got.wm) + assert.NotNil(t, got.userAgg) + require.NotNil(t, got.key) + assert.NotEmpty(t, got.key.URL()) + assert.NotEmpty(t, got.key.Secret()) + assert.Len(t, got.cmds, 1) + } + }) + } +} + +func TestCommands_HumanCheckMFAOTPSetup(t *testing.T) { + ctx := authz.NewMockContext("inst1", "org1", "user1") + + cryptoAlg := crypto.CreateMockEncryptionAlg(gomock.NewController(t)) + key, secret, err := domain.NewOTPKey("example.com", "user1", cryptoAlg) + require.NoError(t, err) + userAgg := &user.NewAggregate("user1", "org1").Aggregate + + code, err := totp.GenerateCode(key.Secret(), time.Now()) + require.NoError(t, err) + + type fields struct { + eventstore *eventstore.Eventstore + } + type args struct { + userID string + code string + resourceOwner string + } + tests := []struct { + name string + fields fields + args args + want bool + wantErr error + }{ + { + name: "missing user id", + args: args{}, + wantErr: caos_errs.ThrowPreconditionFailed(nil, "COMMAND-8N9ds", "Errors.User.UserIDMissing"), + }, + { + name: "filter error", + fields: fields{ + eventstore: eventstoreExpect(t, + expectFilterError(io.ErrClosedPipe), + ), + }, + args: args{ + userID: "user1", + resourceOwner: "org1", + }, + wantErr: io.ErrClosedPipe, + }, + { + name: "otp not existing error", + fields: fields{ + eventstore: eventstoreExpect( + t, + expectFilter( + eventFromEventPusher( + user.NewHumanOTPAddedEvent(ctx, userAgg, secret), + ), + eventFromEventPusher( + user.NewHumanOTPRemovedEvent(ctx, userAgg), + ), + ), + ), + }, + args: args{ + resourceOwner: "org1", + userID: "user1", + }, + wantErr: caos_errs.ThrowNotFound(nil, "COMMAND-3Mif9s", "Errors.User.MFA.OTP.NotExisting"), + }, + { + name: "otp already ready error", + fields: fields{ + eventstore: eventstoreExpect( + t, + expectFilter( + eventFromEventPusher( + user.NewHumanOTPAddedEvent(ctx, userAgg, secret), + ), + eventFromEventPusher( + user.NewHumanOTPVerifiedEvent(context.Background(), + userAgg, + "agent1", + ), + ), + ), + ), + }, + args: args{ + resourceOwner: "org1", + userID: "user1", + }, + wantErr: caos_errs.ThrowPreconditionFailed(nil, "COMMAND-qx4ls", "Errors.Users.MFA.OTP.AlreadyReady"), + }, + { + name: "wrong code", + fields: fields{ + eventstore: eventstoreExpect( + t, + expectFilter( + eventFromEventPusher( + user.NewHumanOTPAddedEvent(ctx, userAgg, secret), + ), + ), + ), + }, + args: args{ + resourceOwner: "org1", + code: "wrong", + userID: "user1", + }, + wantErr: caos_errs.ThrowInvalidArgument(nil, "EVENT-8isk2", "Errors.User.MFA.OTP.InvalidCode"), + }, + { + name: "push error", + fields: fields{ + eventstore: eventstoreExpect( + t, + expectFilter( + eventFromEventPusher( + user.NewHumanOTPAddedEvent(ctx, userAgg, secret), + ), + ), + expectPushFailed(io.ErrClosedPipe, + []*repository.Event{eventFromEventPusher( + user.NewHumanOTPVerifiedEvent(ctx, + userAgg, + "agent1", + ), + )}, + ), + ), + }, + args: args{ + resourceOwner: "org1", + code: code, + userID: "user1", + }, + wantErr: io.ErrClosedPipe, + }, + { + name: "success", + fields: fields{ + eventstore: eventstoreExpect( + t, + expectFilter( + eventFromEventPusher( + user.NewHumanOTPAddedEvent(ctx, userAgg, secret), + ), + ), + expectPush([]*repository.Event{eventFromEventPusher( + user.NewHumanOTPVerifiedEvent(ctx, + userAgg, + "agent1", + ), + )}), + ), + }, + args: args{ + resourceOwner: "org1", + code: code, + userID: "user1", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := &Commands{ + eventstore: tt.fields.eventstore, + multifactors: domain.MultifactorConfigs{ + OTP: domain.OTPConfig{ + CryptoMFA: cryptoAlg, + }, + }, + } + got, err := c.HumanCheckMFAOTPSetup(ctx, tt.args.userID, tt.args.code, "agent1", tt.args.resourceOwner) + require.ErrorIs(t, err, tt.wantErr) + if tt.want { + require.NotNil(t, got) + assert.Equal(t, "org1", got.ResourceOwner) + } + }) + } +} + func TestCommandSide_RemoveHumanOTP(t *testing.T) { type fields struct { eventstore *eventstore.Eventstore diff --git a/internal/command/user_human_password.go b/internal/command/user_human_password.go index 706fe2fcc..8d54727e2 100644 --- a/internal/command/user_human_password.go +++ b/internal/command/user_human_password.go @@ -26,6 +26,9 @@ func (c *Commands) SetPassword(ctx context.Context, orgID, userID, passwordStrin if !existingPassword.UserState.Exists() { return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-3M0fs", "Errors.User.NotFound") } + if err = c.checkPermission(ctx, domain.PermissionUserWrite, existingPassword.ResourceOwner, userID); err != nil { + return nil, err + } password := &domain.Password{ SecretString: passwordString, ChangeRequired: oneTime, @@ -46,28 +49,28 @@ func (c *Commands) SetPassword(ctx context.Context, orgID, userID, passwordStrin return writeModelToObjectDetails(&existingPassword.WriteModel), nil } -func (c *Commands) SetPasswordWithVerifyCode(ctx context.Context, orgID, userID, code, passwordString, userAgentID string, passwordVerificationCode crypto.Generator) (err error) { +func (c *Commands) SetPasswordWithVerifyCode(ctx context.Context, orgID, userID, code, passwordString, userAgentID string) (objectDetails *domain.ObjectDetails, err error) { ctx, span := tracing.NewSpan(ctx) defer func() { span.EndWithError(err) }() if userID == "" { - return caos_errs.ThrowInvalidArgument(nil, "COMMAND-3M9fs", "Errors.IDMissing") + return nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-3M9fs", "Errors.IDMissing") } if passwordString == "" { - return caos_errs.ThrowInvalidArgument(nil, "COMMAND-Mf0sd", "Errors.User.Password.Empty") + return nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-Mf0sd", "Errors.User.Password.Empty") } existingCode, err := c.passwordWriteModel(ctx, userID, orgID) if err != nil { - return err + return nil, err } if existingCode.Code == nil || existingCode.UserState == domain.UserStateUnspecified || existingCode.UserState == domain.UserStateDeleted { - return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-2M9fs", "Errors.User.Code.NotFound") + return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-2M9fs", "Errors.User.Code.NotFound") } - err = crypto.VerifyCode(existingCode.CodeCreationDate, existingCode.CodeExpiry, existingCode.Code, code, passwordVerificationCode) + err = crypto.VerifyCodeWithAlgorithm(existingCode.CodeCreationDate, existingCode.CodeExpiry, existingCode.Code, code, c.userEncryption) if err != nil { - return err + return nil, err } password := &domain.Password{ @@ -77,10 +80,13 @@ func (c *Commands) SetPasswordWithVerifyCode(ctx context.Context, orgID, userID, userAgg := UserAggregateFromWriteModel(&existingCode.WriteModel) passwordEvent, err := c.changePassword(ctx, userAgentID, password, userAgg, existingCode) if err != nil { - return err + return nil, err } - _, err = c.eventstore.Push(ctx, passwordEvent) - return err + err = c.pushAppendAndReduce(ctx, existingCode, passwordEvent) + if err != nil { + return nil, err + } + return writeModelToObjectDetails(&existingCode.WriteModel), nil } func (c *Commands) ChangePassword(ctx context.Context, orgID, userID, oldPassword, newPassword, userAgentID string) (objectDetails *domain.ObjectDetails, err error) { diff --git a/internal/command/user_human_password_test.go b/internal/command/user_human_password_test.go index 883959f40..6eabda952 100644 --- a/internal/command/user_human_password_test.go +++ b/internal/command/user_human_password_test.go @@ -2,6 +2,7 @@ package command import ( "context" + "errors" "testing" "time" @@ -22,6 +23,7 @@ func TestCommandSide_SetOneTimePassword(t *testing.T) { type fields struct { eventstore *eventstore.Eventstore userPasswordAlg crypto.HashAlgorithm + checkPermission domain.PermissionCheck } type args struct { ctx context.Context @@ -72,6 +74,49 @@ func TestCommandSide_SetOneTimePassword(t *testing.T) { err: caos_errs.IsPreconditionFailed, }, }, + { + name: "missing permission, error", + fields: fields{ + eventstore: eventstoreExpect( + t, + expectFilter( + eventFromEventPusher( + user.NewHumanAddedEvent(context.Background(), + &user.NewAggregate("user1", "org1").Aggregate, + "username", + "firstname", + "lastname", + "nickname", + "displayname", + language.German, + domain.GenderUnspecified, + "email@test.ch", + true, + ), + ), + eventFromEventPusher( + user.NewHumanEmailVerifiedEvent(context.Background(), + &user.NewAggregate("user1", "org1").Aggregate, + ), + ), + ), + ), + userPasswordAlg: crypto.CreateMockHashAlg(gomock.NewController(t)), + checkPermission: newMockPermissionCheckNotAllowed(), + }, + args: args{ + ctx: context.Background(), + userID: "user1", + resourceOwner: "org1", + password: "password", + oneTime: true, + }, + res: res{ + err: func(err error) bool { + return errors.Is(err, caos_errs.ThrowPermissionDenied(nil, "AUTHZ-HKJD33", "Errors.PermissionDenied")) + }, + }, + }, { name: "change password onetime, ok", fields: fields{ @@ -129,6 +174,7 @@ func TestCommandSide_SetOneTimePassword(t *testing.T) { ), ), userPasswordAlg: crypto.CreateMockHashAlg(gomock.NewController(t)), + checkPermission: newMockPermissionCheckAllowed(), }, args: args{ ctx: context.Background(), @@ -200,6 +246,7 @@ func TestCommandSide_SetOneTimePassword(t *testing.T) { ), ), userPasswordAlg: crypto.CreateMockHashAlg(gomock.NewController(t)), + checkPermission: newMockPermissionCheckAllowed(), }, args: args{ ctx: context.Background(), @@ -220,6 +267,7 @@ func TestCommandSide_SetOneTimePassword(t *testing.T) { r := &Commands{ eventstore: tt.fields.eventstore, userPasswordAlg: tt.fields.userPasswordAlg, + checkPermission: tt.fields.checkPermission, } got, err := r.SetPassword(tt.args.ctx, tt.args.resourceOwner, tt.args.userID, tt.args.password, tt.args.oneTime) if tt.res.err == nil { @@ -235,19 +283,19 @@ func TestCommandSide_SetOneTimePassword(t *testing.T) { } } -func TestCommandSide_SetPassword(t *testing.T) { +func TestCommandSide_SetPasswordWithVerifyCode(t *testing.T) { type fields struct { eventstore *eventstore.Eventstore + userEncryption crypto.EncryptionAlgorithm userPasswordAlg crypto.HashAlgorithm } type args struct { - ctx context.Context - userID string - code string - resourceOwner string - password string - agentID string - secretGenerator crypto.Generator + ctx context.Context + userID string + code string + resourceOwner string + password string + agentID string } type res struct { want *domain.ObjectDetails @@ -377,14 +425,14 @@ func TestCommandSide_SetPassword(t *testing.T) { ), ), ), + userEncryption: crypto.CreateMockEncryptionAlg(gomock.NewController(t)), }, args: args{ - ctx: context.Background(), - userID: "user1", - code: "test", - resourceOwner: "org1", - password: "password", - secretGenerator: GetMockSecretGenerator(t), + ctx: context.Background(), + userID: "user1", + code: "test", + resourceOwner: "org1", + password: "password", }, res: res{ err: caos_errs.IsPreconditionFailed, @@ -460,14 +508,14 @@ func TestCommandSide_SetPassword(t *testing.T) { ), ), userPasswordAlg: crypto.CreateMockHashAlg(gomock.NewController(t)), + userEncryption: crypto.CreateMockEncryptionAlg(gomock.NewController(t)), }, args: args{ - ctx: context.Background(), - userID: "user1", - resourceOwner: "org1", - password: "password", - code: "a", - secretGenerator: GetMockSecretGenerator(t), + ctx: context.Background(), + userID: "user1", + resourceOwner: "org1", + password: "password", + code: "a", }, res: res{ want: &domain.ObjectDetails{ @@ -481,14 +529,18 @@ func TestCommandSide_SetPassword(t *testing.T) { r := &Commands{ eventstore: tt.fields.eventstore, userPasswordAlg: tt.fields.userPasswordAlg, + userEncryption: tt.fields.userEncryption, } - err := r.SetPasswordWithVerifyCode(tt.args.ctx, tt.args.resourceOwner, tt.args.userID, tt.args.code, tt.args.password, tt.args.agentID, tt.args.secretGenerator) + got, err := r.SetPasswordWithVerifyCode(tt.args.ctx, tt.args.resourceOwner, tt.args.userID, tt.args.code, tt.args.password, tt.args.agentID) if tt.res.err == nil { assert.NoError(t, err) } if tt.res.err != nil && !tt.res.err(err) { t.Errorf("got wrong err: %v ", err) } + if tt.res.err == nil { + assert.Equal(t, tt.res.want, got) + } }) } } diff --git a/internal/command/user_human_webauthn.go b/internal/command/user_human_webauthn.go index 5156b5f8f..c5e03bf3d 100644 --- a/internal/command/user_human_webauthn.go +++ b/internal/command/user_human_webauthn.go @@ -27,8 +27,8 @@ func (c *Commands) getHumanU2FTokens(ctx context.Context, userID, resourceowner return readModelToU2FTokens(tokenReadModel), nil } -func (c *Commands) getHumanPasswordlessTokens(ctx context.Context, userID, resourceowner string) ([]*domain.WebAuthNToken, error) { - tokenReadModel := NewHumanPasswordlessTokensReadModel(userID, resourceowner) +func (c *Commands) getHumanPasswordlessTokens(ctx context.Context, userID, resourceOwner string) ([]*domain.WebAuthNToken, error) { + tokenReadModel := NewHumanPasswordlessTokensReadModel(userID, resourceOwner) err := c.eventstore.FilterToQueryReducer(ctx, tokenReadModel) if err != nil { return nil, err @@ -82,12 +82,12 @@ func (c *Commands) HumanAddU2FSetup(ctx context.Context, userID, resourceowner s if err != nil { return nil, err } - addWebAuthN, userAgg, webAuthN, err := c.addHumanWebAuthN(ctx, userID, resourceowner, isLoginUI, u2fTokens, domain.AuthenticatorAttachmentUnspecified, domain.UserVerificationRequirementDiscouraged) + addWebAuthN, userAgg, webAuthN, err := c.addHumanWebAuthN(ctx, userID, resourceowner, "", u2fTokens, domain.AuthenticatorAttachmentUnspecified, domain.UserVerificationRequirementDiscouraged) if err != nil { return nil, err } - events, err := c.eventstore.Push(ctx, usr_repo.NewHumanU2FAddedEvent(ctx, userAgg, addWebAuthN.WebauthNTokenID, webAuthN.Challenge)) + events, err := c.eventstore.Push(ctx, usr_repo.NewHumanU2FAddedEvent(ctx, userAgg, addWebAuthN.WebauthNTokenID, webAuthN.Challenge, "")) if err != nil { return nil, err } @@ -108,12 +108,12 @@ func (c *Commands) HumanAddPasswordlessSetup(ctx context.Context, userID, resour if err != nil { return nil, err } - addWebAuthN, userAgg, webAuthN, err := c.addHumanWebAuthN(ctx, userID, resourceowner, isLoginUI, passwordlessTokens, authenticatorPlatform, domain.UserVerificationRequirementRequired) + addWebAuthN, userAgg, webAuthN, err := c.addHumanWebAuthN(ctx, userID, resourceowner, "", passwordlessTokens, authenticatorPlatform, domain.UserVerificationRequirementRequired) if err != nil { return nil, err } - events, err := c.eventstore.Push(ctx, usr_repo.NewHumanPasswordlessAddedEvent(ctx, userAgg, addWebAuthN.WebauthNTokenID, webAuthN.Challenge)) + events, err := c.eventstore.Push(ctx, usr_repo.NewHumanPasswordlessAddedEvent(ctx, userAgg, addWebAuthN.WebauthNTokenID, webAuthN.Challenge, "")) if err != nil { return nil, err } @@ -137,7 +137,7 @@ func (c *Commands) HumanAddPasswordlessSetupInitCode(ctx context.Context, userID return c.HumanAddPasswordlessSetup(ctx, userID, resourceowner, true, preferredPlatformType) } -func (c *Commands) addHumanWebAuthN(ctx context.Context, userID, resourceowner string, isLoginUI bool, tokens []*domain.WebAuthNToken, authenticatorPlatform domain.AuthenticatorAttachment, userVerification domain.UserVerificationRequirement) (*HumanWebAuthNWriteModel, *eventstore.Aggregate, *domain.WebAuthNToken, error) { +func (c *Commands) addHumanWebAuthN(ctx context.Context, userID, resourceowner, rpID string, tokens []*domain.WebAuthNToken, authenticatorPlatform domain.AuthenticatorAttachment, userVerification domain.UserVerificationRequirement) (*HumanWebAuthNWriteModel, *eventstore.Aggregate, *domain.WebAuthNToken, error) { if userID == "" { return nil, nil, nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-3M0od", "Errors.IDMissing") } @@ -157,7 +157,7 @@ func (c *Commands) addHumanWebAuthN(ctx context.Context, userID, resourceowner s if accountName == "" { accountName = string(user.EmailAddress) } - webAuthN, err := c.webauthnConfig.BeginRegistration(ctx, user, accountName, authenticatorPlatform, userVerification, isLoginUI, tokens...) + webAuthN, err := c.webauthnConfig.BeginRegistration(ctx, user, accountName, authenticatorPlatform, userVerification, rpID, tokens...) if err != nil { return nil, nil, nil, err } @@ -343,7 +343,7 @@ func (c *Commands) beginWebAuthNLogin(ctx context.Context, userID, resourceOwner if err != nil { return nil, nil, err } - webAuthNLogin, err := c.webauthnConfig.BeginLogin(ctx, human, userVerification, tokens...) + webAuthNLogin, err := c.webauthnConfig.BeginLogin(ctx, human, userVerification, "", tokens...) if err != nil { return nil, nil, err } diff --git a/internal/command/user_human_webauthn_model.go b/internal/command/user_human_webauthn_model.go index b92e35dbd..daf9e880d 100644 --- a/internal/command/user_human_webauthn_model.go +++ b/internal/command/user_human_webauthn_model.go @@ -21,6 +21,7 @@ type HumanWebAuthNWriteModel struct { AAGUID []byte SignCount uint32 WebAuthNTokenName string + RPID string State domain.MFAState } @@ -113,6 +114,7 @@ func (wm *HumanWebAuthNWriteModel) Reduce() error { func (wm *HumanWebAuthNWriteModel) appendAddedEvent(e *user.HumanWebAuthNAddedEvent) { wm.WebauthNTokenID = e.WebAuthNTokenID wm.Challenge = e.Challenge + wm.RPID = e.RPID wm.State = domain.MFAStateNotReady } diff --git a/internal/command/user_idp_link_model.go b/internal/command/user_idp_link_model.go index 0682afb31..41ff5c6d5 100644 --- a/internal/command/user_idp_link_model.go +++ b/internal/command/user_idp_link_model.go @@ -31,17 +31,17 @@ func (wm *UserIDPLinkWriteModel) AppendEvents(events ...eventstore.Event) { for _, event := range events { switch e := event.(type) { case *user.UserIDPLinkAddedEvent: - if e.IDPConfigID != wm.IDPConfigID && e.ExternalUserID != wm.ExternalUserID { + if e.IDPConfigID != wm.IDPConfigID || e.ExternalUserID != wm.ExternalUserID { continue } wm.WriteModel.AppendEvents(e) case *user.UserIDPLinkRemovedEvent: - if e.IDPConfigID != wm.IDPConfigID && e.ExternalUserID != wm.ExternalUserID { + if e.IDPConfigID != wm.IDPConfigID || e.ExternalUserID != wm.ExternalUserID { continue } wm.WriteModel.AppendEvents(e) case *user.UserIDPLinkCascadeRemovedEvent: - if e.IDPConfigID != wm.IDPConfigID && e.ExternalUserID != wm.ExternalUserID { + if e.IDPConfigID != wm.IDPConfigID || e.ExternalUserID != wm.ExternalUserID { continue } wm.WriteModel.AppendEvents(e) diff --git a/internal/command/user_v2_passkey.go b/internal/command/user_v2_passkey.go index 2795e6df8..f08a0632c 100644 --- a/internal/command/user_v2_passkey.go +++ b/internal/command/user_v2_passkey.go @@ -15,23 +15,23 @@ import ( ) // 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) { +// UserID, usually taken from the request is compared against the user ID in the context. +func (c *Commands) RegisterUserPasskey(ctx context.Context, userID, resourceOwner, rpID string, authenticator domain.AuthenticatorAttachment) (*domain.WebAuthNRegistrationDetails, error) { if err := authz.UserIDInCTX(ctx, userID); err != nil { return nil, err } - return c.registerUserPasskey(ctx, userID, resourceOwner, authenticator) + return c.registerUserPasskey(ctx, userID, resourceOwner, rpID, 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) { +func (c *Commands) RegisterUserPasskeyWithCode(ctx context.Context, userID, resourceOwner string, authenticator domain.AuthenticatorAttachment, codeID, code, rpID string, alg crypto.EncryptionAlgorithm) (*domain.WebAuthNRegistrationDetails, 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) + return c.registerUserPasskey(ctx, userID, resourceOwner, rpID, authenticator, event) } type eventCallback func(context.Context, *eventstore.Aggregate) eventstore.Command @@ -40,7 +40,7 @@ type eventCallback func(context.Context, *eventstore.Aggregate) eventstore.Comma // 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. +// This prevents 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) @@ -63,25 +63,25 @@ func (c *Commands) verifyUserPasskeyCodeFailed(ctx context.Context, wm *HumanPas 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) +func (c *Commands) registerUserPasskey(ctx context.Context, userID, resourceOwner, rpID string, authenticator domain.AuthenticatorAttachment, events ...eventCallback) (*domain.WebAuthNRegistrationDetails, error) { + wm, userAgg, webAuthN, err := c.createUserPasskey(ctx, userID, resourceOwner, rpID, 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) { +func (c *Commands) createUserPasskey(ctx context.Context, userID, resourceOwner, rpID 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) + return c.addHumanWebAuthN(ctx, userID, resourceOwner, rpID, passwordlessTokens, authenticator, domain.UserVerificationRequirementRequired) } -func (c *Commands) pushUserPasskey(ctx context.Context, wm *HumanWebAuthNWriteModel, userAgg *eventstore.Aggregate, webAuthN *domain.WebAuthNToken, events ...eventCallback) (*domain.PasskeyRegistrationDetails, error) { +func (c *Commands) pushUserPasskey(ctx context.Context, wm *HumanWebAuthNWriteModel, userAgg *eventstore.Aggregate, webAuthN *domain.WebAuthNToken, events ...eventCallback) (*domain.WebAuthNRegistrationDetails, error) { cmds := make([]eventstore.Command, len(events)+1) - cmds[0] = user.NewHumanPasswordlessAddedEvent(ctx, userAgg, wm.WebauthNTokenID, webAuthN.Challenge) + cmds[0] = user.NewHumanPasswordlessAddedEvent(ctx, userAgg, wm.WebauthNTokenID, webAuthN.Challenge, webAuthN.RPID) for i, event := range events { cmds[i+1] = event(ctx, userAgg) } @@ -90,9 +90,9 @@ func (c *Commands) pushUserPasskey(ctx context.Context, wm *HumanWebAuthNWriteMo if err != nil { return nil, err } - return &domain.PasskeyRegistrationDetails{ + return &domain.WebAuthNRegistrationDetails{ ObjectDetails: writeModelToObjectDetails(&wm.WriteModel), - PasskeyID: wm.WebauthNTokenID, + ID: wm.WebauthNTokenID, PublicKeyCredentialCreationOptions: webAuthN.CredentialCreationData, }, nil } @@ -122,7 +122,7 @@ func (c *Commands) AddUserPasskeyCodeURLTemplate(ctx context.Context, userID, re } // AddUserPasskeyCodeReturn generates and returns a Passkey code. -// No email will be send to the user. +// No email will be sent 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) } diff --git a/internal/command/user_v2_passkey_test.go b/internal/command/user_v2_passkey_test.go index aefa9685a..1885f6ab2 100644 --- a/internal/command/user_v2_passkey_test.go +++ b/internal/command/user_v2_passkey_test.go @@ -40,13 +40,14 @@ func TestCommands_RegisterUserPasskey(t *testing.T) { type args struct { userID string resourceOwner string + rpID string authenticator domain.AuthenticatorAttachment } tests := []struct { name string fields fields args args - want *domain.PasskeyRegistrationDetails + want *domain.WebAuthNRegistrationDetails wantErr error }{ { @@ -121,7 +122,7 @@ func TestCommands_RegisterUserPasskey(t *testing.T) { idGenerator: tt.fields.idGenerator, webauthnConfig: webauthnConfig, } - _, err := c.RegisterUserPasskey(ctx, tt.args.userID, tt.args.resourceOwner, tt.args.authenticator) + _, err := c.RegisterUserPasskey(ctx, tt.args.userID, tt.args.resourceOwner, tt.args.rpID, tt.args.authenticator) require.ErrorIs(t, err, tt.wantErr) // successful case can't be tested due to random challenge. }) @@ -148,6 +149,7 @@ func TestCommands_RegisterUserPasskeyWithCode(t *testing.T) { type args struct { userID string resourceOwner string + rpID string authenticator domain.AuthenticatorAttachment codeID string code string @@ -222,7 +224,7 @@ func TestCommands_RegisterUserPasskeyWithCode(t *testing.T) { 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) + _, err := c.RegisterUserPasskeyWithCode(ctx, tt.args.userID, tt.args.resourceOwner, tt.args.authenticator, tt.args.codeID, tt.args.code, tt.args.rpID, alg) require.ErrorIs(t, err, tt.wantErr) // successful case can't be tested due to random challenge. }) @@ -376,7 +378,7 @@ func TestCommands_pushUserPasskey(t *testing.T) { expectFilter(eventFromEventPusher( user.NewHumanWebAuthNAddedEvent(eventstore.NewBaseEventForPush( ctx, &org.NewAggregate("org1").Aggregate, user.HumanPasswordlessTokenAddedType, - ), "111", "challenge"), + ), "111", "challenge", "rpID"), )), } @@ -394,7 +396,7 @@ func TestCommands_pushUserPasskey(t *testing.T) { expectPush: func(challenge string) expect { return expectPushFailed(io.ErrClosedPipe, []*repository.Event{eventFromEventPusher( user.NewHumanPasswordlessAddedEvent(ctx, - userAgg, "123", challenge, + userAgg, "123", challenge, "rpID", ), )}) }, @@ -406,7 +408,7 @@ func TestCommands_pushUserPasskey(t *testing.T) { expectPush: func(challenge string) expect { return expectPush([]*repository.Event{eventFromEventPusher( user.NewHumanPasswordlessAddedEvent(ctx, - userAgg, "123", challenge, + userAgg, "123", challenge, "rpID", ), )}) }, @@ -418,7 +420,7 @@ func TestCommands_pushUserPasskey(t *testing.T) { return expectPush([]*repository.Event{ eventFromEventPusher( user.NewHumanPasswordlessAddedEvent(ctx, - userAgg, "123", challenge, + userAgg, "123", challenge, "rpID", ), ), eventFromEventPusher( @@ -440,7 +442,7 @@ func TestCommands_pushUserPasskey(t *testing.T) { webauthnConfig: webauthnConfig, idGenerator: id_mock.NewIDGeneratorExpectIDs(t, "123"), } - wm, userAgg, webAuthN, err := c.createUserPasskey(ctx, "user1", "org1", domain.AuthenticatorAttachmentCrossPlattform) + wm, userAgg, webAuthN, err := c.createUserPasskey(ctx, "user1", "org1", "rpID", domain.AuthenticatorAttachmentCrossPlattform) require.NoError(t, err) c.eventstore = eventstoreExpect(t, tt.expectPush(webAuthN.Challenge)) @@ -449,7 +451,7 @@ func TestCommands_pushUserPasskey(t *testing.T) { require.ErrorIs(t, err, tt.wantErr) if tt.wantErr == nil { assert.NotEmpty(t, got.PublicKeyCredentialCreationOptions) - assert.Equal(t, "123", got.PasskeyID) + assert.Equal(t, "123", got.ID) assert.Equal(t, "org1", got.ObjectDetails.ResourceOwner) } }) diff --git a/internal/command/user_v2_password.go b/internal/command/user_v2_password.go new file mode 100644 index 000000000..53b25c5e4 --- /dev/null +++ b/internal/command/user_v2_password.go @@ -0,0 +1,71 @@ +package command + +import ( + "context" + "io" + + "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/repository/user" +) + +// RequestPasswordReset generates a code +// and triggers a notification e-mail with the default confirmation URL format. +func (c *Commands) RequestPasswordReset(ctx context.Context, userID string) (*domain.ObjectDetails, *string, error) { + return c.requestPasswordReset(ctx, userID, false, "", domain.NotificationTypeEmail) +} + +// RequestPasswordResetURLTemplate generates a code +// and triggers a notification e-mail with the confirmation URL rendered from the passed urlTmpl. +// urlTmpl must be a valid [tmpl.Template]. +func (c *Commands) RequestPasswordResetURLTemplate(ctx context.Context, userID, urlTmpl string, notificationType domain.NotificationType) (*domain.ObjectDetails, *string, error) { + if err := domain.RenderConfirmURLTemplate(io.Discard, urlTmpl, userID, "code", "orgID"); err != nil { + return nil, nil, err + } + return c.requestPasswordReset(ctx, userID, false, urlTmpl, notificationType) +} + +// RequestPasswordResetReturnCode generates a code and does not send a notification email. +// The generated plain text code will be returned. +func (c *Commands) RequestPasswordResetReturnCode(ctx context.Context, userID string) (*domain.ObjectDetails, *string, error) { + return c.requestPasswordReset(ctx, userID, true, "", 0) +} + +// requestPasswordReset creates a code for a password change. +// returnCode controls if the plain text version of the code will be set in the return object. +// When the plain text code is returned, no notification e-mail will be sent to the user. +// urlTmpl allows changing the target URL that is used by the e-mail and should be a validated Go template, if used. +func (c *Commands) requestPasswordReset(ctx context.Context, userID string, returnCode bool, urlTmpl string, notificationType domain.NotificationType) (_ *domain.ObjectDetails, plainCode *string, err error) { + if userID == "" { + return nil, nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-SAFdda", "Errors.User.IDMissing") + } + model, err := c.getHumanWriteModelByID(ctx, userID, "") + if err != nil { + return nil, nil, err + } + if !model.UserState.Exists() { + return nil, nil, caos_errs.ThrowNotFound(nil, "COMMAND-SAF4f", "Errors.User.NotFound") + } + if model.UserState == domain.UserStateInitial { + return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-Sfe4g", "Errors.User.NotInitialised") + } + if authz.GetCtxData(ctx).UserID != userID { + if err = c.checkPermission(ctx, domain.PermissionUserWrite, model.ResourceOwner, userID); err != nil { + return nil, nil, err + } + } + code, err := c.newCode(ctx, c.eventstore.Filter, domain.SecretGeneratorTypePasswordResetCode, c.userEncryption) + if err != nil { + return nil, nil, err + } + cmd := user.NewHumanPasswordCodeAddedEventV2(ctx, UserAggregateFromWriteModel(&model.WriteModel), code.Crypted, code.Expiry, notificationType, urlTmpl, returnCode) + + if returnCode { + plainCode = &code.Plain + } + if err = c.pushAppendAndReduce(ctx, model, cmd); err != nil { + return nil, nil, err + } + return writeModelToObjectDetails(&model.WriteModel), plainCode, nil +} diff --git a/internal/command/user_v2_password_test.go b/internal/command/user_v2_password_test.go new file mode 100644 index 000000000..ecf21ff18 --- /dev/null +++ b/internal/command/user_v2_password_test.go @@ -0,0 +1,611 @@ +package command + +import ( + "context" + "testing" + "time" + + "github.com/muhlemmer/gu" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "golang.org/x/text/language" + + "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" +) + +func TestCommands_RequestPasswordReset(t *testing.T) { + type fields struct { + checkPermission domain.PermissionCheck + eventstore func(t *testing.T) *eventstore.Eventstore + userEncryption crypto.EncryptionAlgorithm + } + type args struct { + ctx context.Context + userID string + } + tests := []struct { + name string + fields fields + args args + wantErr error + }{ + { + name: "missing userID", + fields: fields{ + eventstore: expectEventstore(), + }, + args: args{ + ctx: context.Background(), + userID: "", + }, + wantErr: caos_errs.ThrowInvalidArgument(nil, "COMMAND-SAFdda", "Errors.User.IDMissing"), + }, + { + name: "user not existing", + fields: fields{ + eventstore: expectEventstore( + expectFilter(), + ), + }, + args: args{ + ctx: context.Background(), + userID: "userID", + }, + wantErr: caos_errs.ThrowNotFound(nil, "COMMAND-SAF4f", "Errors.User.NotFound"), + }, + { + name: "user not initialized", + fields: fields{ + eventstore: expectEventstore( + expectFilter( + eventFromEventPusher( + user.NewHumanAddedEvent(context.Background(), &user.NewAggregate("userID", "org1").Aggregate, + "username", "firstname", "lastname", "nickname", "displayname", + language.English, domain.GenderUnspecified, "email", false), + ), + eventFromEventPusher( + user.NewHumanInitialCodeAddedEvent(context.Background(), &user.NewAggregate("userID", "org1").Aggregate, + &crypto.CryptoValue{CryptoType: crypto.TypeEncryption, Algorithm: "enc", KeyID: "keyID", Crypted: []byte("code")}, 10*time.Second), + ), + ), + ), + }, + args: args{ + ctx: context.Background(), + userID: "userID", + }, + wantErr: caos_errs.ThrowPreconditionFailed(nil, "COMMAND-Sfe4g", "Errors.User.NotInitialised"), + }, + { + name: "missing permission", + fields: fields{ + eventstore: expectEventstore( + expectFilter( + eventFromEventPusher( + user.NewHumanAddedEvent(context.Background(), &user.NewAggregate("userID", "org1").Aggregate, + "username", "firstname", "lastname", "nickname", "displayname", + language.English, domain.GenderUnspecified, "email", false), + ), + ), + ), + checkPermission: newMockPermissionCheckNotAllowed(), + }, + args: args{ + ctx: context.Background(), + userID: "userID", + }, + wantErr: caos_errs.ThrowPermissionDenied(nil, "AUTHZ-HKJD33", "Errors.PermissionDenied"), + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := &Commands{ + checkPermission: tt.fields.checkPermission, + eventstore: tt.fields.eventstore(t), + userEncryption: tt.fields.userEncryption, + } + _, _, err := c.RequestPasswordReset(tt.args.ctx, tt.args.userID) + require.ErrorIs(t, err, tt.wantErr) + // successful cases are tested in TestCommands_requestPasswordReset + }) + } +} + +func TestCommands_RequestPasswordResetReturnCode(t *testing.T) { + type fields struct { + checkPermission domain.PermissionCheck + eventstore func(t *testing.T) *eventstore.Eventstore + userEncryption crypto.EncryptionAlgorithm + } + type args struct { + ctx context.Context + userID string + } + tests := []struct { + name string + fields fields + args args + wantErr error + }{ + { + name: "missing userID", + fields: fields{ + eventstore: expectEventstore(), + }, + args: args{ + ctx: context.Background(), + userID: "", + }, + wantErr: caos_errs.ThrowInvalidArgument(nil, "COMMAND-SAFdda", "Errors.User.IDMissing"), + }, + { + name: "user not existing", + fields: fields{ + eventstore: expectEventstore( + expectFilter(), + ), + }, + args: args{ + ctx: context.Background(), + userID: "userID", + }, + wantErr: caos_errs.ThrowNotFound(nil, "COMMAND-SAF4f", "Errors.User.NotFound"), + }, + { + name: "user not initialized", + fields: fields{ + eventstore: expectEventstore( + expectFilter( + eventFromEventPusher( + user.NewHumanAddedEvent(context.Background(), &user.NewAggregate("userID", "org1").Aggregate, + "username", "firstname", "lastname", "nickname", "displayname", + language.English, domain.GenderUnspecified, "email", false), + ), + eventFromEventPusher( + user.NewHumanInitialCodeAddedEvent(context.Background(), &user.NewAggregate("userID", "org1").Aggregate, + &crypto.CryptoValue{CryptoType: crypto.TypeEncryption, Algorithm: "enc", KeyID: "keyID", Crypted: []byte("code")}, 10*time.Second), + ), + ), + ), + }, + args: args{ + ctx: context.Background(), + userID: "userID", + }, + wantErr: caos_errs.ThrowPreconditionFailed(nil, "COMMAND-Sfe4g", "Errors.User.NotInitialised"), + }, + { + name: "missing permission", + fields: fields{ + eventstore: expectEventstore( + expectFilter( + eventFromEventPusher( + user.NewHumanAddedEvent(context.Background(), &user.NewAggregate("userID", "org1").Aggregate, + "username", "firstname", "lastname", "nickname", "displayname", + language.English, domain.GenderUnspecified, "email", false), + ), + ), + ), + checkPermission: newMockPermissionCheckNotAllowed(), + }, + args: args{ + ctx: context.Background(), + userID: "userID", + }, + wantErr: caos_errs.ThrowPermissionDenied(nil, "AUTHZ-HKJD33", "Errors.PermissionDenied"), + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := &Commands{ + checkPermission: tt.fields.checkPermission, + eventstore: tt.fields.eventstore(t), + userEncryption: tt.fields.userEncryption, + } + _, _, err := c.RequestPasswordResetReturnCode(tt.args.ctx, tt.args.userID) + require.ErrorIs(t, err, tt.wantErr) + // successful cases are tested in TestCommands_requestPasswordReset + }) + } +} + +func TestCommands_RequestPasswordResetURLTemplate(t *testing.T) { + type fields struct { + checkPermission domain.PermissionCheck + eventstore func(t *testing.T) *eventstore.Eventstore + userEncryption crypto.EncryptionAlgorithm + } + type args struct { + ctx context.Context + userID string + urlTmpl string + notificationType domain.NotificationType + } + tests := []struct { + name string + fields fields + args args + wantErr error + }{ + { + name: "invalid template", + fields: fields{ + eventstore: expectEventstore(), + }, + args: args{ + userID: "user1", + urlTmpl: "{{", + }, + wantErr: caos_errs.ThrowInvalidArgument(nil, "DOMAIN-oGh5e", "Errors.User.InvalidURLTemplate"), + }, + + { + name: "missing userID", + fields: fields{ + eventstore: expectEventstore(), + }, + args: args{ + ctx: context.Background(), + userID: "", + }, + wantErr: caos_errs.ThrowInvalidArgument(nil, "COMMAND-SAFdda", "Errors.User.IDMissing"), + }, + { + name: "user not existing", + fields: fields{ + eventstore: expectEventstore( + expectFilter(), + ), + }, + args: args{ + ctx: context.Background(), + userID: "userID", + }, + wantErr: caos_errs.ThrowNotFound(nil, "COMMAND-SAF4f", "Errors.User.NotFound"), + }, + { + name: "user not initialized", + fields: fields{ + eventstore: expectEventstore( + expectFilter( + eventFromEventPusher( + user.NewHumanAddedEvent(context.Background(), &user.NewAggregate("userID", "org1").Aggregate, + "username", "firstname", "lastname", "nickname", "displayname", + language.English, domain.GenderUnspecified, "email", false), + ), + eventFromEventPusher( + user.NewHumanInitialCodeAddedEvent(context.Background(), &user.NewAggregate("userID", "org1").Aggregate, + &crypto.CryptoValue{CryptoType: crypto.TypeEncryption, Algorithm: "enc", KeyID: "keyID", Crypted: []byte("code")}, 10*time.Second), + ), + ), + ), + }, + args: args{ + ctx: context.Background(), + userID: "userID", + }, + wantErr: caos_errs.ThrowPreconditionFailed(nil, "COMMAND-Sfe4g", "Errors.User.NotInitialised"), + }, + { + name: "missing permission", + fields: fields{ + eventstore: expectEventstore( + expectFilter( + eventFromEventPusher( + user.NewHumanAddedEvent(context.Background(), &user.NewAggregate("userID", "org1").Aggregate, + "username", "firstname", "lastname", "nickname", "displayname", + language.English, domain.GenderUnspecified, "email", false), + ), + ), + ), + checkPermission: newMockPermissionCheckNotAllowed(), + }, + args: args{ + ctx: context.Background(), + userID: "userID", + }, + wantErr: caos_errs.ThrowPermissionDenied(nil, "AUTHZ-HKJD33", "Errors.PermissionDenied"), + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := &Commands{ + checkPermission: tt.fields.checkPermission, + eventstore: tt.fields.eventstore(t), + userEncryption: tt.fields.userEncryption, + } + _, _, err := c.RequestPasswordResetURLTemplate(tt.args.ctx, tt.args.userID, tt.args.urlTmpl, tt.args.notificationType) + require.ErrorIs(t, err, tt.wantErr) + // successful cases are tested in TestCommands_requestPasswordReset + }) + } +} + +func TestCommands_requestPasswordReset(t *testing.T) { + type fields struct { + checkPermission domain.PermissionCheck + eventstore func(t *testing.T) *eventstore.Eventstore + userEncryption crypto.EncryptionAlgorithm + newCode cryptoCodeFunc + } + type args struct { + ctx context.Context + userID string + returnCode bool + urlTmpl string + notificationType domain.NotificationType + } + type res struct { + details *domain.ObjectDetails + code *string + err error + } + tests := []struct { + name string + fields fields + args args + res res + }{ + { + name: "missing userID", + fields: fields{ + eventstore: expectEventstore(), + }, + args: args{ + ctx: context.Background(), + userID: "", + }, + res: res{ + err: caos_errs.ThrowInvalidArgument(nil, "COMMAND-SAFdda", "Errors.User.IDMissing"), + }, + }, + { + name: "user not existing", + fields: fields{ + eventstore: expectEventstore( + expectFilter(), + ), + }, + args: args{ + ctx: context.Background(), + userID: "userID", + }, + res: res{ + err: caos_errs.ThrowNotFound(nil, "COMMAND-SAF4f", "Errors.User.NotFound"), + }, + }, + { + name: "user not initialized", + fields: fields{ + eventstore: expectEventstore( + expectFilter( + eventFromEventPusher( + user.NewHumanAddedEvent(context.Background(), &user.NewAggregate("userID", "org1").Aggregate, + "username", "firstname", "lastname", "nickname", "displayname", + language.English, domain.GenderUnspecified, "email", false), + ), + eventFromEventPusher( + user.NewHumanInitialCodeAddedEvent(context.Background(), &user.NewAggregate("userID", "org1").Aggregate, + &crypto.CryptoValue{CryptoType: crypto.TypeEncryption, Algorithm: "enc", KeyID: "keyID", Crypted: []byte("code")}, 10*time.Second), + ), + ), + ), + }, + args: args{ + ctx: context.Background(), + userID: "userID", + }, + res: res{ + err: caos_errs.ThrowPreconditionFailed(nil, "COMMAND-Sfe4g", "Errors.User.NotInitialised"), + }, + }, + { + name: "missing permission", + fields: fields{ + eventstore: expectEventstore( + expectFilter( + eventFromEventPusher( + user.NewHumanAddedEvent(context.Background(), &user.NewAggregate("userID", "org1").Aggregate, + "username", "firstname", "lastname", "nickname", "displayname", + language.English, domain.GenderUnspecified, "email", false), + ), + ), + ), + checkPermission: newMockPermissionCheckNotAllowed(), + }, + args: args{ + ctx: context.Background(), + userID: "userID", + }, + res: res{ + err: caos_errs.ThrowPermissionDenied(nil, "AUTHZ-HKJD33", "Errors.PermissionDenied"), + }, + }, + { + name: "code generated", + fields: fields{ + eventstore: expectEventstore( + expectFilter( + eventFromEventPusher( + user.NewHumanAddedEvent(context.Background(), &user.NewAggregate("userID", "org1").Aggregate, + "username", "firstname", "lastname", "nickname", "displayname", + language.English, domain.GenderUnspecified, "email", false), + ), + ), + expectPush( + eventPusherToEvents( + user.NewHumanPasswordCodeAddedEventV2(context.Background(), &user.NewAggregate("userID", "org1").Aggregate, + &crypto.CryptoValue{ + CryptoType: crypto.TypeEncryption, + Algorithm: "enc", + KeyID: "id", + Crypted: []byte("code"), + }, + 10*time.Minute, + domain.NotificationTypeEmail, + "", + false, + )), + ), + ), + checkPermission: newMockPermissionCheckAllowed(), + newCode: mockCode("code", 10*time.Minute), + }, + args: args{ + ctx: context.Background(), + userID: "userID", + }, + res: res{ + details: &domain.ObjectDetails{ + ResourceOwner: "org1", + }, + code: nil, + }, + }, + { + name: "code generated template", + fields: fields{ + eventstore: expectEventstore( + expectFilter( + eventFromEventPusher( + user.NewHumanAddedEvent(context.Background(), &user.NewAggregate("userID", "org1").Aggregate, + "username", "firstname", "lastname", "nickname", "displayname", + language.English, domain.GenderUnspecified, "email", false), + ), + ), + expectPush( + eventPusherToEvents( + user.NewHumanPasswordCodeAddedEventV2(context.Background(), &user.NewAggregate("userID", "org1").Aggregate, + &crypto.CryptoValue{ + CryptoType: crypto.TypeEncryption, + Algorithm: "enc", + KeyID: "id", + Crypted: []byte("code"), + }, + 10*time.Minute, + domain.NotificationTypeEmail, + "https://example.com/password/changey?userID={{.UserID}}&code={{.Code}}&orgID={{.OrgID}}", + false, + )), + ), + ), + checkPermission: newMockPermissionCheckAllowed(), + newCode: mockCode("code", 10*time.Minute), + }, + args: args{ + ctx: context.Background(), + userID: "userID", + urlTmpl: "https://example.com/password/changey?userID={{.UserID}}&code={{.Code}}&orgID={{.OrgID}}", + }, + res: res{ + details: &domain.ObjectDetails{ + ResourceOwner: "org1", + }, + code: nil, + }, + }, + { + name: "code generated template sms", + fields: fields{ + eventstore: expectEventstore( + expectFilter( + eventFromEventPusher( + user.NewHumanAddedEvent(context.Background(), &user.NewAggregate("userID", "org1").Aggregate, + "username", "firstname", "lastname", "nickname", "displayname", + language.English, domain.GenderUnspecified, "email", false), + ), + ), + expectPush( + eventPusherToEvents( + user.NewHumanPasswordCodeAddedEventV2(context.Background(), &user.NewAggregate("userID", "org1").Aggregate, + &crypto.CryptoValue{ + CryptoType: crypto.TypeEncryption, + Algorithm: "enc", + KeyID: "id", + Crypted: []byte("code"), + }, + 10*time.Minute, + domain.NotificationTypeSms, + "https://example.com/password/changey?userID={{.UserID}}&code={{.Code}}&orgID={{.OrgID}}", + false, + )), + ), + ), + checkPermission: newMockPermissionCheckAllowed(), + newCode: mockCode("code", 10*time.Minute), + }, + args: args{ + ctx: context.Background(), + userID: "userID", + urlTmpl: "https://example.com/password/changey?userID={{.UserID}}&code={{.Code}}&orgID={{.OrgID}}", + notificationType: domain.NotificationTypeSms, + }, + res: res{ + details: &domain.ObjectDetails{ + ResourceOwner: "org1", + }, + code: nil, + }, + }, + { + name: "code generated returned", + fields: fields{ + eventstore: expectEventstore( + expectFilter( + eventFromEventPusher( + user.NewHumanAddedEvent(context.Background(), &user.NewAggregate("userID", "org1").Aggregate, + "username", "firstname", "lastname", "nickname", "displayname", + language.English, domain.GenderUnspecified, "email", false), + ), + ), + expectPush( + eventPusherToEvents( + user.NewHumanPasswordCodeAddedEventV2(context.Background(), &user.NewAggregate("userID", "org1").Aggregate, + &crypto.CryptoValue{ + CryptoType: crypto.TypeEncryption, + Algorithm: "enc", + KeyID: "id", + Crypted: []byte("code"), + }, + 10*time.Minute, + domain.NotificationTypeEmail, + "", + true, + )), + ), + ), + checkPermission: newMockPermissionCheckAllowed(), + newCode: mockCode("code", 10*time.Minute), + }, + args: args{ + ctx: context.Background(), + userID: "userID", + returnCode: true, + }, + res: res{ + details: &domain.ObjectDetails{ + ResourceOwner: "org1", + }, + code: gu.Ptr("code"), + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := &Commands{ + checkPermission: tt.fields.checkPermission, + eventstore: tt.fields.eventstore(t), + userEncryption: tt.fields.userEncryption, + newCode: tt.fields.newCode, + } + got, gotPlainCode, err := c.requestPasswordReset(tt.args.ctx, tt.args.userID, tt.args.returnCode, tt.args.urlTmpl, tt.args.notificationType) + require.ErrorIs(t, err, tt.res.err) + assert.Equal(t, tt.res.details, got) + assert.Equal(t, tt.res.code, gotPlainCode) + }) + } +} diff --git a/internal/command/user_v2_totp.go b/internal/command/user_v2_totp.go new file mode 100644 index 000000000..76840bac1 --- /dev/null +++ b/internal/command/user_v2_totp.go @@ -0,0 +1,33 @@ +package command + +import ( + "context" + + "github.com/zitadel/zitadel/internal/api/authz" + "github.com/zitadel/zitadel/internal/domain" +) + +func (c *Commands) AddUserTOTP(ctx context.Context, userID, resourceowner string) (*domain.TOTP, error) { + if err := authz.UserIDInCTX(ctx, userID); err != nil { + return nil, err + } + prep, err := c.createHumanTOTP(ctx, userID, resourceowner) + if err != nil { + return nil, err + } + if err = c.pushAppendAndReduce(ctx, prep.wm, prep.cmds...); err != nil { + return nil, err + } + return &domain.TOTP{ + ObjectDetails: writeModelToObjectDetails(&prep.wm.WriteModel), + Secret: prep.key.Secret(), + URI: prep.key.URL(), + }, nil +} + +func (c *Commands) CheckUserTOTP(ctx context.Context, userID, code, resourceOwner string) (*domain.ObjectDetails, error) { + if err := authz.UserIDInCTX(ctx, userID); err != nil { + return nil, err + } + return c.HumanCheckMFAOTPSetup(ctx, userID, code, "", resourceOwner) +} diff --git a/internal/command/user_v2_totp_test.go b/internal/command/user_v2_totp_test.go new file mode 100644 index 000000000..d7b9f8246 --- /dev/null +++ b/internal/command/user_v2_totp_test.go @@ -0,0 +1,263 @@ +package command + +import ( + "io" + "testing" + "time" + + "github.com/golang/mock/gomock" + "github.com/pquerna/otp/totp" + "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/repository/org" + "github.com/zitadel/zitadel/internal/repository/user" +) + +func TestCommands_AddUserTOTP(t *testing.T) { + ctx := authz.NewMockContext("inst1", "org1", "user1") + userAgg := &user.NewAggregate("user1", "org1").Aggregate + + type fields struct { + eventstore *eventstore.Eventstore + } + type args struct { + userID string + resourceowner string + } + tests := []struct { + name string + fields fields + args args + want bool + wantErr error + }{ + { + name: "wrong user", + args: args{ + userID: "foo", + resourceowner: "org1", + }, + wantErr: caos_errs.ThrowUnauthenticated(nil, "AUTH-Bohd2", "Errors.User.UserIDWrong"), + }, + { + name: "create otp error", + args: args{ + userID: "user1", + resourceowner: "org1", + }, + fields: fields{ + eventstore: eventstoreExpect( + t, + expectFilter(), + ), + }, + wantErr: caos_errs.ThrowPreconditionFailed(nil, "COMMAND-MM9fs", "Errors.User.NotFound"), + }, + { + name: "push error", + args: args{ + userID: "user1", + resourceowner: "org1", + }, + fields: fields{ + eventstore: eventstoreExpect( + t, + expectFilter( + eventFromEventPusher( + user.NewHumanAddedEvent(ctx, + userAgg, + "username", + "firstname", + "lastname", + "nickname", + "displayname", + language.German, + domain.GenderUnspecified, + "email@test.ch", + true, + ), + ), + ), + expectFilter( + eventFromEventPusher( + org.NewOrgAddedEvent(ctx, + userAgg, + "org", + ), + ), + ), + expectFilter( + eventFromEventPusher( + org.NewDomainPolicyAddedEvent(ctx, + userAgg, + true, + true, + true, + ), + ), + ), + expectFilter(), + expectRandomPushFailed(io.ErrClosedPipe, []*repository.Event{eventFromEventPusher( + user.NewHumanOTPAddedEvent(ctx, userAgg, nil), + )}), + ), + }, + wantErr: io.ErrClosedPipe, + }, + { + name: "success", + args: args{ + userID: "user1", + resourceowner: "org1", + }, + fields: fields{ + eventstore: eventstoreExpect( + t, + expectFilter( + eventFromEventPusher( + user.NewHumanAddedEvent(ctx, + userAgg, + "username", + "firstname", + "lastname", + "nickname", + "displayname", + language.German, + domain.GenderUnspecified, + "email@test.ch", + true, + ), + ), + ), + expectFilter( + eventFromEventPusher( + org.NewOrgAddedEvent(ctx, + userAgg, + "org", + ), + ), + ), + expectFilter( + eventFromEventPusher( + org.NewDomainPolicyAddedEvent(ctx, + userAgg, + true, + true, + true, + ), + ), + ), + expectFilter(), + expectRandomPush([]*repository.Event{eventFromEventPusher( + user.NewHumanOTPAddedEvent(ctx, userAgg, nil), + )}), + ), + }, + want: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := &Commands{ + eventstore: tt.fields.eventstore, + multifactors: domain.MultifactorConfigs{ + OTP: domain.OTPConfig{ + Issuer: "zitadel.com", + CryptoMFA: crypto.CreateMockEncryptionAlg(gomock.NewController(t)), + }, + }, + } + got, err := c.AddUserTOTP(ctx, tt.args.userID, tt.args.resourceowner) + require.ErrorIs(t, err, tt.wantErr) + if tt.want { + require.NotNil(t, got) + assert.Equal(t, "org1", got.ResourceOwner) + assert.NotEmpty(t, got.Secret) + assert.NotEmpty(t, got.URI) + } + }) + } +} + +func TestCommands_CheckUserTOTP(t *testing.T) { + ctx := authz.NewMockContext("inst1", "org1", "user1") + + cryptoAlg := crypto.CreateMockEncryptionAlg(gomock.NewController(t)) + key, secret, err := domain.NewOTPKey("example.com", "user1", cryptoAlg) + require.NoError(t, err) + userAgg := &user.NewAggregate("user1", "org1").Aggregate + + code, err := totp.GenerateCode(key.Secret(), time.Now()) + require.NoError(t, err) + + type fields struct { + eventstore *eventstore.Eventstore + } + type args struct { + userID string + code string + resourceOwner string + } + tests := []struct { + name string + fields fields + args args + want bool + wantErr error + }{ + { + name: "wrong user id", + args: args{ + userID: "foo", + }, + wantErr: caos_errs.ThrowUnauthenticated(nil, "AUTH-Bohd2", "Errors.User.UserIDWrong"), + }, + { + name: "success", + fields: fields{ + eventstore: eventstoreExpect( + t, + expectFilter( + eventFromEventPusher( + user.NewHumanOTPAddedEvent(ctx, userAgg, secret), + ), + ), + expectPush([]*repository.Event{eventFromEventPusher( + user.NewHumanOTPVerifiedEvent(ctx, userAgg, ""), + )}), + ), + }, + args: args{ + resourceOwner: "org1", + code: code, + userID: "user1", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := &Commands{ + eventstore: tt.fields.eventstore, + multifactors: domain.MultifactorConfigs{ + OTP: domain.OTPConfig{ + CryptoMFA: cryptoAlg, + }, + }, + } + got, err := c.CheckUserTOTP(ctx, tt.args.userID, tt.args.code, tt.args.resourceOwner) + require.ErrorIs(t, err, tt.wantErr) + if tt.want { + require.NotNil(t, got) + assert.Equal(t, "org1", got.ResourceOwner) + } + }) + } +} diff --git a/internal/command/user_v2_u2f.go b/internal/command/user_v2_u2f.go new file mode 100644 index 000000000..50c16aa30 --- /dev/null +++ b/internal/command/user_v2_u2f.go @@ -0,0 +1,46 @@ +package command + +import ( + "context" + + "github.com/zitadel/zitadel/internal/api/authz" + "github.com/zitadel/zitadel/internal/domain" + "github.com/zitadel/zitadel/internal/eventstore" + "github.com/zitadel/zitadel/internal/repository/user" +) + +func (c *Commands) RegisterUserU2F(ctx context.Context, userID, resourceOwner, rpID string) (*domain.WebAuthNRegistrationDetails, error) { + if err := authz.UserIDInCTX(ctx, userID); err != nil { + return nil, err + } + return c.registerUserU2F(ctx, userID, resourceOwner, rpID) +} + +func (c *Commands) registerUserU2F(ctx context.Context, userID, resourceOwner, rpID string) (*domain.WebAuthNRegistrationDetails, error) { + wm, userAgg, webAuthN, err := c.createUserU2F(ctx, userID, resourceOwner, rpID) + if err != nil { + return nil, err + } + return c.pushUserU2F(ctx, wm, userAgg, webAuthN) +} + +func (c *Commands) createUserU2F(ctx context.Context, userID, resourceOwner, rpID string) (*HumanWebAuthNWriteModel, *eventstore.Aggregate, *domain.WebAuthNToken, error) { + tokens, err := c.getHumanU2FTokens(ctx, userID, resourceOwner) + if err != nil { + return nil, nil, nil, err + } + return c.addHumanWebAuthN(ctx, userID, resourceOwner, rpID, tokens, domain.AuthenticatorAttachmentUnspecified, domain.UserVerificationRequirementRequired) +} + +func (c *Commands) pushUserU2F(ctx context.Context, wm *HumanWebAuthNWriteModel, userAgg *eventstore.Aggregate, webAuthN *domain.WebAuthNToken) (*domain.WebAuthNRegistrationDetails, error) { + cmd := user.NewHumanU2FAddedEvent(ctx, userAgg, wm.WebauthNTokenID, webAuthN.Challenge, webAuthN.RPID) + err := c.pushAppendAndReduce(ctx, wm, cmd) + if err != nil { + return nil, err + } + return &domain.WebAuthNRegistrationDetails{ + ObjectDetails: writeModelToObjectDetails(&wm.WriteModel), + ID: wm.WebauthNTokenID, + PublicKeyCredentialCreationOptions: webAuthN.CredentialCreationData, + }, nil +} diff --git a/internal/command/user_v2_u2f_test.go b/internal/command/user_v2_u2f_test.go new file mode 100644 index 000000000..ebab0a4ce --- /dev/null +++ b/internal/command/user_v2_u2f_test.go @@ -0,0 +1,216 @@ +package command + +import ( + "context" + "io" + "testing" + + "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/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_RegisterUserU2F(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 + rpID string + } + tests := []struct { + name string + fields fields + args args + want *domain.WebAuthNRegistrationDetails + wantErr error + }{ + { + name: "wrong user", + args: args{ + userID: "foo", + resourceOwner: "org1", + }, + 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", + }, + 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", + }, + 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.RegisterUserU2F(ctx, tt.args.userID, tt.args.resourceOwner, tt.args.rpID) + require.ErrorIs(t, err, tt.wantErr) + // successful case can't be tested due to random challenge. + }) + } +} + +func TestCommands_pushUserU2F(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(), // getHumanU2FTokens + 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", "rpID"), + )), + } + + tests := []struct { + name string + expectPush func(challenge string) expect + wantErr error + }{ + { + name: "push error", + expectPush: func(challenge string) expect { + return expectPushFailed(io.ErrClosedPipe, []*repository.Event{eventFromEventPusher( + user.NewHumanU2FAddedEvent(ctx, + userAgg, "123", challenge, "rpID", + ), + )}) + }, + wantErr: io.ErrClosedPipe, + }, + { + name: "success", + expectPush: func(challenge string) expect { + return expectPush([]*repository.Event{eventFromEventPusher( + user.NewHumanU2FAddedEvent(ctx, + userAgg, "123", challenge, "rpID", + ), + )}) + }, + }, + } + 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", "rpID", domain.AuthenticatorAttachmentCrossPlattform) + require.NoError(t, err) + + c.eventstore = eventstoreExpect(t, tt.expectPush(webAuthN.Challenge)) + + got, err := c.pushUserU2F(ctx, wm, userAgg, webAuthN) + require.ErrorIs(t, err, tt.wantErr) + if tt.wantErr == nil { + assert.NotEmpty(t, got.PublicKeyCredentialCreationOptions) + assert.Equal(t, "123", got.ID) + assert.Equal(t, "org1", got.ObjectDetails.ResourceOwner) + } + }) + } +} diff --git a/internal/crypto/code.go b/internal/crypto/code.go index 8901b8e27..60d1496ec 100644 --- a/internal/crypto/code.go +++ b/internal/crypto/code.go @@ -121,10 +121,14 @@ func IsCodeExpired(creationDate time.Time, expiry time.Duration) bool { } func VerifyCode(creationDate time.Time, expiry time.Duration, cryptoCode *CryptoValue, verificationCode string, g Generator) error { + return VerifyCodeWithAlgorithm(creationDate, expiry, cryptoCode, verificationCode, g.Alg()) +} + +func VerifyCodeWithAlgorithm(creationDate time.Time, expiry time.Duration, cryptoCode *CryptoValue, verificationCode string, algorithm Crypto) error { if IsCodeExpired(creationDate, expiry) { return errors.ThrowPreconditionFailed(nil, "CODE-QvUQ4P", "Errors.User.Code.Expired") } - switch alg := g.Alg().(type) { + switch alg := algorithm.(type) { case EncryptionAlgorithm: return verifyEncryptedCode(cryptoCode, verificationCode, alg) case HashAlgorithm: diff --git a/internal/crypto/code_test.go b/internal/crypto/code_test.go index 47c173d77..302ab141a 100644 --- a/internal/crypto/code_test.go +++ b/internal/crypto/code_test.go @@ -71,7 +71,7 @@ func TestVerifyCode(t *testing.T) { expiry: 5 * time.Minute, cryptoCode: nil, verificationCode: "", - g: nil, + g: createMockGenerator(t, createMockCrypto(t)), }, true, }, diff --git a/internal/crypto/crypto.go b/internal/crypto/crypto.go index 9799faea6..748a124b5 100644 --- a/internal/crypto/crypto.go +++ b/internal/crypto/crypto.go @@ -2,6 +2,7 @@ package crypto import ( "database/sql/driver" + "encoding/base64" "encoding/json" "github.com/zitadel/zitadel/internal/errors" @@ -132,3 +133,21 @@ func FillHash(value []byte, alg HashAlgorithm) *CryptoValue { Crypted: value, } } + +func CheckToken(alg EncryptionAlgorithm, token string, content string) error { + if token == "" { + return errors.ThrowPermissionDenied(nil, "CRYPTO-Sfefs", "Errors.Intent.InvalidToken") + } + data, err := base64.RawURLEncoding.DecodeString(token) + if err != nil { + return errors.ThrowPermissionDenied(err, "CRYPTO-Swg31", "Errors.Intent.InvalidToken") + } + decryptedToken, err := alg.DecryptString(data, alg.EncryptionKeyID()) + if err != nil { + return errors.ThrowPermissionDenied(err, "CRYPTO-Sf4gt", "Errors.Intent.InvalidToken") + } + if decryptedToken != content { + return errors.ThrowPermissionDenied(nil, "CRYPTO-CRYPTO", "Errors.Intent.InvalidToken") + } + return nil +} diff --git a/internal/domain/application_oidc.go b/internal/domain/application_oidc.go index e0ae783e8..ac2918478 100644 --- a/internal/domain/application_oidc.go +++ b/internal/domain/application_oidc.go @@ -213,7 +213,7 @@ func GetOIDCV1Compliance(appType OIDCApplicationType, grantTypes []OIDCGrantType checkGrantTypesCombination(compliance, grantTypes) checkRedirectURIs(compliance, grantTypes, appType, redirectUris) - checkApplicaitonType(compliance, appType, authMethod) + checkApplicationType(compliance, appType, authMethod) if compliance.NoneCompliant { compliance.Problems = append([]string{"Application.OIDC.V1.NotCompliant"}, compliance.Problems...) @@ -246,7 +246,7 @@ func checkRedirectURIs(compliance *Compliance, grantTypes []OIDCGrantType, appTy } } -func checkApplicaitonType(compliance *Compliance, appType OIDCApplicationType, authMethod OIDCAuthMethodType) { +func checkApplicationType(compliance *Compliance, appType OIDCApplicationType, authMethod OIDCAuthMethodType) { switch appType { case OIDCApplicationTypeNative: GetOIDCV1NativeApplicationCompliance(compliance, authMethod) diff --git a/internal/domain/human_otp.go b/internal/domain/human_otp.go index 354f9b174..479814340 100644 --- a/internal/domain/human_otp.go +++ b/internal/domain/human_otp.go @@ -17,10 +17,17 @@ type OTP struct { State MFAState } +type TOTP struct { + *ObjectDetails + + Secret string + URI string +} + func NewOTPKey(issuer, accountName string, cryptoAlg crypto.EncryptionAlgorithm) (*otp.Key, *crypto.CryptoValue, error) { key, err := totp.Generate(totp.GenerateOpts{Issuer: issuer, AccountName: accountName}) if err != nil { - return nil, nil, err + return nil, nil, caos_errs.ThrowInternal(err, "TOTP-ieY3o", "Errors.Internal") } encryptedSecret, err := crypto.Encrypt([]byte(key.Secret()), cryptoAlg) if err != nil { diff --git a/internal/domain/human_web_auth_n.go b/internal/domain/human_web_auth_n.go index 8b1a7134b..16590d43c 100644 --- a/internal/domain/human_web_auth_n.go +++ b/internal/domain/human_web_auth_n.go @@ -23,6 +23,7 @@ type WebAuthNToken struct { AAGUID []byte SignCount uint32 WebAuthNTokenName string + RPID string } type WebAuthNLogin struct { @@ -32,6 +33,7 @@ type WebAuthNLogin struct { Challenge string AllowedCredentialIDs [][]byte UserVerification UserVerificationRequirement + RPID string } type UserVerificationRequirement int32 diff --git a/internal/domain/permission.go b/internal/domain/permission.go index 5a51d7bdb..ebd7981ab 100644 --- a/internal/domain/permission.go +++ b/internal/domain/permission.go @@ -28,7 +28,7 @@ type PermissionCheck func(ctx context.Context, permission, orgID, resourceID str const ( PermissionUserWrite = "user.write" - PermissionSessionRead = "session.read" + PermissionUserRead = "user.read" PermissionSessionWrite = "session.write" PermissionSessionDelete = "session.delete" ) diff --git a/internal/domain/user.go b/internal/domain/user.go index 157edcc19..a5e01361f 100644 --- a/internal/domain/user.go +++ b/internal/domain/user.go @@ -51,6 +51,8 @@ const ( UserAuthMethodTypeOTP UserAuthMethodTypeU2F UserAuthMethodTypePasswordless + UserAuthMethodTypePassword + UserAuthMethodTypeIDP userAuthMethodTypeCount ) diff --git a/internal/domain/user_v2_passkey.go b/internal/domain/user_v2_passkey.go index 37f34097e..69d7b4a35 100644 --- a/internal/domain/user_v2_passkey.go +++ b/internal/domain/user_v2_passkey.go @@ -21,9 +21,9 @@ type PasskeyCodeDetails struct { Code string } -type PasskeyRegistrationDetails struct { +type WebAuthNRegistrationDetails struct { *ObjectDetails - PasskeyID string + ID string PublicKeyCredentialCreationOptions []byte } diff --git a/internal/eventstore/handler/crdb/statement.go b/internal/eventstore/handler/crdb/statement.go index 8601630cd..591751e66 100644 --- a/internal/eventstore/handler/crdb/statement.go +++ b/internal/eventstore/handler/crdb/statement.go @@ -285,6 +285,16 @@ func NewCopyCol(column, from string) handler.Column { } } +func NewLessThanCond(column string, value interface{}) handler.Condition { + return handler.Condition{ + Name: column, + Value: value, + ParameterOpt: func(placeholder string) string { + return " < " + placeholder + }, + } +} + // NewCopyStatement creates a new upsert statement which updates a column from an existing row // cols represent the columns which are objective to change. // if the value of a col is empty the data will be copied from the selected row @@ -390,6 +400,9 @@ func conditionsToWhere(cols []handler.Condition, paramOffset int) (wheres []stri for i, col := range cols { wheres[i] = "(" + col.Name + " = $" + strconv.Itoa(i+1+paramOffset) + ")" + if col.ParameterOpt != nil { + wheres[i] = "(" + col.Name + col.ParameterOpt("$"+strconv.Itoa(i+1+paramOffset)) + ")" + } values[i] = col.Value } diff --git a/internal/eventstore/repository/mock/repository.mock.impl.go b/internal/eventstore/repository/mock/repository.mock.impl.go index 9121d1379..e21f4fd7c 100644 --- a/internal/eventstore/repository/mock/repository.mock.impl.go +++ b/internal/eventstore/repository/mock/repository.mock.impl.go @@ -70,3 +70,25 @@ func (m *MockRepository) ExpectPushFailed(err error, expectedEvents []*repositor ) return m } + +func (m *MockRepository) ExpectRandomPush(expectedEvents []*repository.Event, expectedUniqueConstraints ...*repository.UniqueConstraint) *MockRepository { + m.EXPECT().Push(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn( + func(ctx context.Context, events []*repository.Event, uniqueConstraints ...*repository.UniqueConstraint) error { + assert.Len(m.ctrl.T, events, len(expectedEvents)) + assert.Len(m.ctrl.T, expectedUniqueConstraints, len(uniqueConstraints)) + return nil + }, + ) + return m +} + +func (m *MockRepository) ExpectRandomPushFailed(err error, expectedEvents []*repository.Event, expectedUniqueConstraints ...*repository.UniqueConstraint) *MockRepository { + m.EXPECT().Push(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn( + func(ctx context.Context, events []*repository.Event, uniqueConstraints ...*repository.UniqueConstraint) error { + assert.Len(m.ctrl.T, events, len(expectedEvents)) + assert.Len(m.ctrl.T, expectedUniqueConstraints, len(uniqueConstraints)) + return err + }, + ) + return m +} diff --git a/internal/integration/client.go b/internal/integration/client.go index c21b42f67..86b78bb87 100644 --- a/internal/integration/client.go +++ b/internal/integration/client.go @@ -3,12 +3,21 @@ package integration import ( "context" "fmt" + "testing" "time" + "github.com/stretchr/testify/require" "github.com/zitadel/logging" + "github.com/zitadel/oidc/v2/pkg/oidc" + "golang.org/x/oauth2" "google.golang.org/grpc" + "github.com/zitadel/zitadel/internal/api/authz" + "github.com/zitadel/zitadel/internal/command" + openid "github.com/zitadel/zitadel/internal/idp/providers/oidc" + "github.com/zitadel/zitadel/internal/repository/idp" "github.com/zitadel/zitadel/pkg/grpc/admin" + mgmt "github.com/zitadel/zitadel/pkg/grpc/management" object "github.com/zitadel/zitadel/pkg/grpc/object/v2alpha" session "github.com/zitadel/zitadel/pkg/grpc/session/v2alpha" user "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha" @@ -17,6 +26,7 @@ import ( type Client struct { CC *grpc.ClientConn Admin admin.AdminServiceClient + Mgmt mgmt.ManagementServiceClient UserV2 user.UserServiceClient SessionV2 session.SessionServiceClient } @@ -25,6 +35,7 @@ func newClient(cc *grpc.ClientConn) Client { return Client{ CC: cc, Admin: admin.NewAdminServiceClient(cc), + Mgmt: mgmt.NewManagementServiceClient(cc), UserV2: user.NewUserServiceClient(cc), SessionV2: session.NewSessionServiceClient(cc), } @@ -52,6 +63,22 @@ func (s *Tester) CreateHumanUser(ctx context.Context) *user.AddHumanUserResponse return resp } +func (s *Tester) CreateUserIDPlink(ctx context.Context, userID, externalID, idpID, username string) *user.AddIDPLinkResponse { + resp, err := s.Client.UserV2.AddIDPLink( + ctx, + &user.AddIDPLinkRequest{ + UserId: userID, + IdpLink: &user.IDPLink{ + IdpId: idpID, + UserId: externalID, + UserName: username, + }, + }, + ) + logging.OnError(err).Fatal("create human user link") + return resp +} + func (s *Tester) RegisterUserPasskey(ctx context.Context, userID string) { reg, err := s.Client.UserV2.CreatePasskeyRegistrationLink(ctx, &user.CreatePasskeyRegistrationLinkRequest{ UserId: userID, @@ -62,6 +89,7 @@ func (s *Tester) RegisterUserPasskey(ctx context.Context, userID string) { pkr, err := s.Client.UserV2.RegisterPasskey(ctx, &user.RegisterPasskeyRequest{ UserId: userID, Code: reg.GetCode(), + Domain: s.Config.ExternalDomain, }) logging.OnError(err).Fatal("create user passkey") attestationResponse, err := s.WebAuthN.CreateAttestationResponse(pkr.GetPublicKeyCredentialCreationOptions()) @@ -75,3 +103,58 @@ func (s *Tester) RegisterUserPasskey(ctx context.Context, userID string) { }) logging.OnError(err).Fatal("create user passkey") } + +func (s *Tester) AddGenericOAuthProvider(t *testing.T) string { + ctx := authz.WithInstance(context.Background(), s.Instance) + id, _, err := s.Commands.AddOrgGenericOAuthProvider(ctx, s.Organisation.ID, command.GenericOAuthProvider{ + Name: "idp", + ClientID: "clientID", + ClientSecret: "clientSecret", + AuthorizationEndpoint: "https://example.com/oauth/v2/authorize", + TokenEndpoint: "https://example.com/oauth/v2/token", + UserEndpoint: "https://api.example.com/user", + Scopes: []string{"openid", "profile", "email"}, + IDAttribute: "id", + IDPOptions: idp.Options{ + IsLinkingAllowed: true, + IsCreationAllowed: true, + IsAutoCreation: true, + IsAutoUpdate: true, + }, + }) + require.NoError(t, err) + return id +} + +func (s *Tester) CreateIntent(t *testing.T, idpID string) string { + ctx := authz.WithInstance(context.Background(), s.Instance) + id, _, err := s.Commands.CreateIntent(ctx, idpID, "https://example.com/success", "https://example.com/failure", s.Organisation.ID) + require.NoError(t, err) + return id +} + +func (s *Tester) CreateSuccessfulIntent(t *testing.T, idpID, userID, idpUserID string) (string, string, time.Time, uint64) { + ctx := authz.WithInstance(context.Background(), s.Instance) + intentID := s.CreateIntent(t, idpID) + writeModel, err := s.Commands.GetIntentWriteModel(ctx, intentID, s.Organisation.ID) + require.NoError(t, err) + idpUser := openid.NewUser( + &oidc.UserInfo{ + Subject: idpUserID, + UserInfoProfile: oidc.UserInfoProfile{ + PreferredUsername: "username", + }, + }, + ) + idpSession := &openid.Session{ + Tokens: &oidc.Tokens[*oidc.IDTokenClaims]{ + Token: &oauth2.Token{ + AccessToken: "accessToken", + }, + IDToken: "idToken", + }, + } + token, err := s.Commands.SucceedIDPIntent(ctx, writeModel, idpUser, idpSession, userID) + require.NoError(t, err) + return intentID, token, writeModel.ChangeDate, writeModel.ProcessedSequence +} diff --git a/internal/notification/handlers/usernotifier.go b/internal/notification/handlers/usernotifier.go index 5cd810236..cd2a48f09 100644 --- a/internal/notification/handlers/usernotifier.go +++ b/internal/notification/handlers/usernotifier.go @@ -251,6 +251,9 @@ func (u *userNotifier) reducePasswordCodeAdded(event eventstore.Event) (*handler if !ok { return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-Eeg3s", "reduce.wrong.event.type %s", user.HumanPasswordCodeAddedType) } + if e.CodeReturned { + return crdb.NewNoOpStatement(e), nil + } ctx := HandlerContext(event.Aggregate()) alreadyHandled, err := u.checkIfCodeAlreadyHandledOrExpired(ctx, event, e.Expiry, nil, user.UserV1PasswordCodeAddedType, user.UserV1PasswordCodeSentType, @@ -317,7 +320,7 @@ func (u *userNotifier) reducePasswordCodeAdded(event eventstore.Event) (*handler u.metricFailedDeliveriesSMS, ) } - err = notify.SendPasswordCode(notifyUser, origin, code) + err = notify.SendPasswordCode(notifyUser, origin, code, e.URLTemplate) if err != nil { return nil, err } diff --git a/internal/notification/static/i18n/bg.yaml b/internal/notification/static/i18n/bg.yaml new file mode 100644 index 000000000..963eeb272 --- /dev/null +++ b/internal/notification/static/i18n/bg.yaml @@ -0,0 +1,59 @@ +InitCode: + Title: ZITADEL - Инициализиране на потребител + PreHeader: Инициализиране на потребителя + Subject: Инициализиране на потребителя + Greeting: 'Здравейте {{.DisplayName}},' + Text: >- + Този потребител е създаден в ZITADEL. {{.PreferredLoginName}} за да + влезете. {{.Code}}) Ако не сте поискали този имейл, моля, игнорирайте го. + ButtonText: Завършете инициализацията +PasswordReset: + Title: ZITADEL - Нулиране на парола + PreHeader: Нулирайте паролата + Subject: Нулирайте паролата + Greeting: 'Здравейте {{.DisplayName}},' + Text: >- + Получихме заявка за повторно задаване на парола. {{.Code}}) Ако не сте + поискали този имейл, моля, игнорирайте го. + ButtonText: Нулирайте паролата +VerifyEmail: + Title: ZITADEL - Потвърдете имейл + PreHeader: Потвърди Имейл + Subject: Потвърди Имейл + Greeting: 'Здравейте {{.DisplayName}},' + Text: >- + Добавен е нов имейл. {{.Code}}) Ако не сте добавили нов имейл, моля, + игнорирайте този имейл. + ButtonText: Потвърди Имейл +VerifyPhone: + Title: ZITADEL - Потвърдете телефона + PreHeader: Потвърдете телефона + Subject: Потвърдете телефона + Greeting: 'Здравейте {{.DisplayName}},' + Text: 'Добавен е нов телефонен номер. {{.Code}}' + ButtonText: Потвърдете телефона +DomainClaimed: + Title: ZITADEL - Домейнът е заявен + PreHeader: Промяна на имейл/потребителско име + Subject: Домейнът е заявен + Greeting: 'Здравейте {{.DisplayName}},' + Text: >- + Домейнът {{.Domain}} е заявено от организация. {{.Username}} не е част от + тази организация. {{.TempUsername}}) за това влизане. + ButtonText: Влизам +PasswordlessRegistration: + Title: ZITADEL - Добавете вход без парола + PreHeader: Добавете вход без парола + Subject: Добавете вход без парола + Greeting: 'Здравейте {{.DisplayName}},' + Text: 'Получихме заявка за добавяне на токен за влизане без парола. ' + ButtonText: Добавете вход без парола +PasswordChange: + Title: ZITADEL - Паролата на потребителя е променена + PreHeader: Промяна на паролата + Subject: Паролата на потребителя е променена + Greeting: 'Здравейте {{.DisplayName}},' + Text: >- + Паролата на вашия потребител е променена, ако тази промяна не е направена от + вас, моля, незабавно нулирайте паролата си. + ButtonText: Влизам diff --git a/internal/notification/types/password_code.go b/internal/notification/types/password_code.go index e9b5df529..2285ba439 100644 --- a/internal/notification/types/password_code.go +++ b/internal/notification/types/password_code.go @@ -1,13 +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) SendPasswordCode(user *query.NotifyUser, origin, code string) error { - url := login.InitPasswordLink(origin, user.ID, code, user.ResourceOwner) +func (notify Notify) SendPasswordCode(user *query.NotifyUser, origin, code, urlTmpl string) error { + var url string + if urlTmpl == "" { + url = login.InitPasswordLink(origin, user.ID, code, user.ResourceOwner) + } else { + var buf strings.Builder + if err := domain.RenderConfirmURLTemplate(&buf, urlTmpl, user.ID, code, user.ResourceOwner); err != nil { + return err + } + url = buf.String() + } args := make(map[string]interface{}) args["Code"] = code return notify(url, args, domain.PasswordResetMessageType, true) diff --git a/internal/query/projection/session.go b/internal/query/projection/session.go index d40302a84..2fceb2243 100644 --- a/internal/query/projection/session.go +++ b/internal/query/projection/session.go @@ -10,10 +10,11 @@ import ( "github.com/zitadel/zitadel/internal/eventstore/handler/crdb" "github.com/zitadel/zitadel/internal/repository/instance" "github.com/zitadel/zitadel/internal/repository/session" + "github.com/zitadel/zitadel/internal/repository/user" ) const ( - SessionsProjectionTable = "projections.sessions1" + SessionsProjectionTable = "projections.sessions3" SessionColumnID = "id" SessionColumnCreationDate = "creation_date" @@ -21,11 +22,13 @@ const ( SessionColumnSequence = "sequence" SessionColumnState = "state" SessionColumnResourceOwner = "resource_owner" + SessionColumnDomain = "domain" SessionColumnInstanceID = "instance_id" SessionColumnCreator = "creator" SessionColumnUserID = "user_id" SessionColumnUserCheckedAt = "user_checked_at" SessionColumnPasswordCheckedAt = "password_checked_at" + SessionColumnIntentCheckedAt = "intent_checked_at" SessionColumnPasskeyCheckedAt = "passkey_checked_at" SessionColumnMetadata = "metadata" SessionColumnTokenID = "token_id" @@ -47,11 +50,13 @@ func newSessionProjection(ctx context.Context, config crdb.StatementHandlerConfi crdb.NewColumn(SessionColumnSequence, crdb.ColumnTypeInt64), crdb.NewColumn(SessionColumnState, crdb.ColumnTypeEnum), crdb.NewColumn(SessionColumnResourceOwner, crdb.ColumnTypeText), + crdb.NewColumn(SessionColumnDomain, crdb.ColumnTypeText), crdb.NewColumn(SessionColumnInstanceID, crdb.ColumnTypeText), crdb.NewColumn(SessionColumnCreator, crdb.ColumnTypeText), crdb.NewColumn(SessionColumnUserID, crdb.ColumnTypeText, crdb.Nullable()), crdb.NewColumn(SessionColumnUserCheckedAt, crdb.ColumnTypeTimestamp, crdb.Nullable()), crdb.NewColumn(SessionColumnPasswordCheckedAt, crdb.ColumnTypeTimestamp, crdb.Nullable()), + crdb.NewColumn(SessionColumnIntentCheckedAt, crdb.ColumnTypeTimestamp, crdb.Nullable()), crdb.NewColumn(SessionColumnPasskeyCheckedAt, crdb.ColumnTypeTimestamp, crdb.Nullable()), crdb.NewColumn(SessionColumnMetadata, crdb.ColumnTypeJSONB, crdb.Nullable()), crdb.NewColumn(SessionColumnTokenID, crdb.ColumnTypeText, crdb.Nullable()), @@ -80,6 +85,10 @@ func (p *sessionProjection) reducers() []handler.AggregateReducer { Event: session.PasswordCheckedType, Reduce: p.reducePasswordChecked, }, + { + Event: session.IntentCheckedType, + Reduce: p.reduceIntentChecked, + }, { Event: session.PasskeyCheckedType, Reduce: p.reducePasskeyChecked, @@ -107,6 +116,15 @@ func (p *sessionProjection) reducers() []handler.AggregateReducer { }, }, }, + { + Aggregate: user.AggregateType, + EventRedusers: []handler.EventReducer{ + { + Event: user.HumanPasswordChangedType, + Reduce: p.reducePasswordChanged, + }, + }, + }, } } @@ -124,6 +142,7 @@ func (p *sessionProjection) reduceSessionAdded(event eventstore.Event) (*handler handler.NewCol(SessionColumnCreationDate, e.CreationDate()), handler.NewCol(SessionColumnChangeDate, e.CreationDate()), handler.NewCol(SessionColumnResourceOwner, e.Aggregate().ResourceOwner), + handler.NewCol(SessionColumnDomain, e.Domain), handler.NewCol(SessionColumnState, domain.SessionStateActive), handler.NewCol(SessionColumnSequence, e.Sequence()), handler.NewCol(SessionColumnCreator, e.User), @@ -171,6 +190,26 @@ func (p *sessionProjection) reducePasswordChecked(event eventstore.Event) (*hand ), nil } +func (p *sessionProjection) reduceIntentChecked(event eventstore.Event) (*handler.Statement, error) { + e, ok := event.(*session.IntentCheckedEvent) + if !ok { + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-SDgr2", "reduce.wrong.event.type %s", session.IntentCheckedType) + } + + return crdb.NewUpdateStatement( + e, + []handler.Column{ + handler.NewCol(SessionColumnChangeDate, e.CreationDate()), + handler.NewCol(SessionColumnSequence, e.Sequence()), + handler.NewCol(SessionColumnIntentCheckedAt, e.CheckedAt), + }, + []handler.Condition{ + handler.NewCond(SessionColumnID, e.Aggregate().ID), + handler.NewCond(SessionColumnInstanceID, e.Aggregate().InstanceID), + }, + ), nil +} + func (p *sessionProjection) reducePasskeyChecked(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*session.PasskeyCheckedEvent) if !ok { @@ -245,3 +284,21 @@ func (p *sessionProjection) reduceSessionTerminated(event eventstore.Event) (*ha }, ), nil } + +func (p *sessionProjection) reducePasswordChanged(event eventstore.Event) (*handler.Statement, error) { + e, ok := event.(*user.HumanPasswordChangedEvent) + if !ok { + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-Deg3d", "reduce.wrong.event.type %s", user.HumanPasswordChangedType) + } + + return crdb.NewUpdateStatement( + e, + []handler.Column{ + handler.NewCol(SessionColumnPasswordCheckedAt, nil), + }, + []handler.Condition{ + handler.NewCond(SessionColumnUserID, e.Aggregate().ID), + crdb.NewLessThanCond(SessionColumnPasswordCheckedAt, e.CreationDate()), + }, + ), nil +} diff --git a/internal/query/projection/session_test.go b/internal/query/projection/session_test.go index ecb96368c..ae19e247e 100644 --- a/internal/query/projection/session_test.go +++ b/internal/query/projection/session_test.go @@ -11,6 +11,7 @@ import ( "github.com/zitadel/zitadel/internal/eventstore/repository" "github.com/zitadel/zitadel/internal/repository/instance" "github.com/zitadel/zitadel/internal/repository/session" + "github.com/zitadel/zitadel/internal/repository/user" ) func TestSessionProjection_reduces(t *testing.T) { @@ -29,7 +30,9 @@ func TestSessionProjection_reduces(t *testing.T) { event: getEvent(testEvent( session.AddedType, session.AggregateType, - []byte(`{}`), + []byte(`{ + "domain": "domain" + }`), ), session.AddedEventMapper), }, reduce: (&sessionProjection{}).reduceSessionAdded, @@ -40,13 +43,14 @@ func TestSessionProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO projections.sessions1 (id, instance_id, creation_date, change_date, resource_owner, state, sequence, creator) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", + expectedStmt: "INSERT INTO projections.sessions3 (id, instance_id, creation_date, change_date, resource_owner, domain, state, sequence, creator) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", expectedArgs: []interface{}{ "agg-id", "instance-id", anyArg{}, anyArg{}, "ro-id", + "domain", domain.SessionStateActive, uint64(15), "editor-user", @@ -76,7 +80,7 @@ func TestSessionProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.sessions1 SET (change_date, sequence, user_id, user_checked_at) = ($1, $2, $3, $4) WHERE (id = $5) AND (instance_id = $6)", + expectedStmt: "UPDATE projections.sessions3 SET (change_date, sequence, user_id, user_checked_at) = ($1, $2, $3, $4) WHERE (id = $5) AND (instance_id = $6)", expectedArgs: []interface{}{ anyArg{}, anyArg{}, @@ -109,7 +113,39 @@ func TestSessionProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.sessions1 SET (change_date, sequence, password_checked_at) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)", + expectedStmt: "UPDATE projections.sessions3 SET (change_date, sequence, password_checked_at) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)", + expectedArgs: []interface{}{ + anyArg{}, + anyArg{}, + time.Date(2023, time.May, 4, 0, 0, 0, 0, time.UTC), + "agg-id", + "instance-id", + }, + }, + }, + }, + }, + }, + { + name: "instance reduceIntentChecked", + args: args{ + event: getEvent(testEvent( + session.AddedType, + session.AggregateType, + []byte(`{ + "checkedAt": "2023-05-04T00:00:00Z" + }`), + ), session.IntentCheckedEventMapper), + }, + reduce: (&sessionProjection{}).reduceIntentChecked, + want: wantReduce{ + aggregateType: eventstore.AggregateType("session"), + sequence: 15, + previousSequence: 10, + executer: &testExecuter{ + executions: []execution{ + { + expectedStmt: "UPDATE projections.sessions3 SET (change_date, sequence, intent_checked_at) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)", expectedArgs: []interface{}{ anyArg{}, anyArg{}, @@ -141,7 +177,7 @@ func TestSessionProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.sessions1 SET (change_date, sequence, token_id) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)", + expectedStmt: "UPDATE projections.sessions3 SET (change_date, sequence, token_id) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)", expectedArgs: []interface{}{ anyArg{}, anyArg{}, @@ -175,7 +211,7 @@ func TestSessionProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.sessions1 SET (change_date, sequence, metadata) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)", + expectedStmt: "UPDATE projections.sessions3 SET (change_date, sequence, metadata) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)", expectedArgs: []interface{}{ anyArg{}, anyArg{}, @@ -207,7 +243,7 @@ func TestSessionProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM projections.sessions1 WHERE (id = $1) AND (instance_id = $2)", + expectedStmt: "DELETE FROM projections.sessions3 WHERE (id = $1) AND (instance_id = $2)", expectedArgs: []interface{}{ "agg-id", "instance-id", @@ -234,7 +270,7 @@ func TestSessionProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM projections.sessions1 WHERE (instance_id = $1)", + expectedStmt: "DELETE FROM projections.sessions3 WHERE (instance_id = $1)", expectedArgs: []interface{}{ "agg-id", }, @@ -243,6 +279,39 @@ func TestSessionProjection_reduces(t *testing.T) { }, }, }, + { + name: "reducePasswordChanged", + args: args{ + event: getEvent(testEvent( + repository.EventType(user.HumanPasswordChangedType), + user.AggregateType, + []byte(`{"secret": { + "cryptoType": 0, + "algorithm": "enc", + "keyID": "id", + "crypted": "cGFzc3dvcmQ=" + }}`), + ), user.HumanPasswordChangedEventMapper), + }, + reduce: (&sessionProjection{}).reducePasswordChanged, + want: wantReduce{ + aggregateType: eventstore.AggregateType("user"), + sequence: 15, + previousSequence: 10, + executer: &testExecuter{ + executions: []execution{ + { + expectedStmt: "UPDATE projections.sessions3 SET password_checked_at = $1 WHERE (user_id = $2) AND (password_checked_at < $3)", + expectedArgs: []interface{}{ + nil, + "agg-id", + anyArg{}, + }, + }, + }, + }, + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/internal/query/query.go b/internal/query/query.go index 17990311b..464cf59aa 100644 --- a/internal/query/query.go +++ b/internal/query/query.go @@ -34,6 +34,7 @@ type Queries struct { idpConfigEncryption crypto.EncryptionAlgorithm sessionTokenVerifier func(ctx context.Context, sessionToken string, sessionID string, tokenID string) (err error) + checkPermission domain.PermissionCheck DefaultLanguage language.Tag LoginDir http.FileSystem @@ -55,6 +56,7 @@ func StartQueries( idpConfigEncryption, otpEncryption, keyEncryptionAlgorithm, certEncryptionAlgorithm crypto.EncryptionAlgorithm, zitadelRoles []authz.RoleMapping, sessionTokenVerifier func(ctx context.Context, sessionToken string, sessionID string, tokenID string) (err error), + permissionCheck func(q *Queries) domain.PermissionCheck, ) (repo *Queries, err error) { statikLoginFS, err := fs.NewWithNamespace("login") if err != nil { @@ -95,6 +97,8 @@ func StartQueries( }, } + repo.checkPermission = permissionCheck(repo) + err = projection.Create(ctx, sqlClient, es, projections, keyEncryptionAlgorithm, certEncryptionAlgorithm) if err != nil { return nil, err diff --git a/internal/query/session.go b/internal/query/session.go index 2dfc622a7..e9706410a 100644 --- a/internal/query/session.go +++ b/internal/query/session.go @@ -29,9 +29,11 @@ type Session struct { Sequence uint64 State domain.SessionState ResourceOwner string + Domain string Creator string UserFactor SessionUserFactor PasswordFactor SessionPasswordFactor + IntentFactor SessionIntentFactor PasskeyFactor SessionPasskeyFactor Metadata map[string][]byte } @@ -47,6 +49,10 @@ type SessionPasswordFactor struct { PasswordCheckedAt time.Time } +type SessionIntentFactor struct { + IntentCheckedAt time.Time +} + type SessionPasskeyFactor struct { PasskeyCheckedAt time.Time } @@ -93,6 +99,10 @@ var ( name: projection.SessionColumnResourceOwner, table: sessionsTable, } + SessionColumnDomain = Column{ + name: projection.SessionColumnDomain, + table: sessionsTable, + } SessionColumnInstanceID = Column{ name: projection.SessionColumnInstanceID, table: sessionsTable, @@ -113,6 +123,10 @@ var ( name: projection.SessionColumnPasswordCheckedAt, table: sessionsTable, } + SessionColumnIntentCheckedAt = Column{ + name: projection.SessionColumnIntentCheckedAt, + table: sessionsTable, + } SessionColumnPasskeyCheckedAt = Column{ name: projection.SessionColumnPasskeyCheckedAt, table: sessionsTable, @@ -202,11 +216,13 @@ func prepareSessionQuery(ctx context.Context, db prepareDatabase) (sq.SelectBuil SessionColumnState.identifier(), SessionColumnResourceOwner.identifier(), SessionColumnCreator.identifier(), + SessionColumnDomain.identifier(), SessionColumnUserID.identifier(), SessionColumnUserCheckedAt.identifier(), LoginNameNameCol.identifier(), HumanDisplayNameCol.identifier(), SessionColumnPasswordCheckedAt.identifier(), + SessionColumnIntentCheckedAt.identifier(), SessionColumnPasskeyCheckedAt.identifier(), SessionColumnMetadata.identifier(), SessionColumnToken.identifier(), @@ -222,9 +238,11 @@ func prepareSessionQuery(ctx context.Context, db prepareDatabase) (sq.SelectBuil loginName sql.NullString displayName sql.NullString passwordCheckedAt sql.NullTime + intentCheckedAt sql.NullTime passkeyCheckedAt sql.NullTime metadata database.Map[[]byte] token sql.NullString + sessionDomain sql.NullString ) err := row.Scan( @@ -235,11 +253,13 @@ func prepareSessionQuery(ctx context.Context, db prepareDatabase) (sq.SelectBuil &session.State, &session.ResourceOwner, &session.Creator, + &sessionDomain, &userID, &userCheckedAt, &loginName, &displayName, &passwordCheckedAt, + &intentCheckedAt, &passkeyCheckedAt, &metadata, &token, @@ -252,11 +272,13 @@ func prepareSessionQuery(ctx context.Context, db prepareDatabase) (sq.SelectBuil return nil, "", errors.ThrowInternal(err, "QUERY-SAder", "Errors.Internal") } + session.Domain = sessionDomain.String session.UserFactor.UserID = userID.String session.UserFactor.UserCheckedAt = userCheckedAt.Time session.UserFactor.LoginName = loginName.String session.UserFactor.DisplayName = displayName.String session.PasswordFactor.PasswordCheckedAt = passwordCheckedAt.Time + session.IntentFactor.IntentCheckedAt = intentCheckedAt.Time session.PasskeyFactor.PasskeyCheckedAt = passkeyCheckedAt.Time session.Metadata = metadata @@ -273,11 +295,13 @@ func prepareSessionsQuery(ctx context.Context, db prepareDatabase) (sq.SelectBui SessionColumnState.identifier(), SessionColumnResourceOwner.identifier(), SessionColumnCreator.identifier(), + SessionColumnDomain.identifier(), SessionColumnUserID.identifier(), SessionColumnUserCheckedAt.identifier(), LoginNameNameCol.identifier(), HumanDisplayNameCol.identifier(), SessionColumnPasswordCheckedAt.identifier(), + SessionColumnIntentCheckedAt.identifier(), SessionColumnPasskeyCheckedAt.identifier(), SessionColumnMetadata.identifier(), countColumn.identifier(), @@ -296,8 +320,10 @@ func prepareSessionsQuery(ctx context.Context, db prepareDatabase) (sq.SelectBui loginName sql.NullString displayName sql.NullString passwordCheckedAt sql.NullTime + intentCheckedAt sql.NullTime passkeyCheckedAt sql.NullTime metadata database.Map[[]byte] + sessionDomain sql.NullString ) err := rows.Scan( @@ -308,11 +334,13 @@ func prepareSessionsQuery(ctx context.Context, db prepareDatabase) (sq.SelectBui &session.State, &session.ResourceOwner, &session.Creator, + &sessionDomain, &userID, &userCheckedAt, &loginName, &displayName, &passwordCheckedAt, + &intentCheckedAt, &passkeyCheckedAt, &metadata, &sessions.Count, @@ -321,11 +349,13 @@ func prepareSessionsQuery(ctx context.Context, db prepareDatabase) (sq.SelectBui if err != nil { return nil, errors.ThrowInternal(err, "QUERY-SAfeg", "Errors.Internal") } + session.Domain = sessionDomain.String session.UserFactor.UserID = userID.String session.UserFactor.UserCheckedAt = userCheckedAt.Time session.UserFactor.LoginName = loginName.String session.UserFactor.DisplayName = displayName.String session.PasswordFactor.PasswordCheckedAt = passwordCheckedAt.Time + session.IntentFactor.IntentCheckedAt = intentCheckedAt.Time session.PasskeyFactor.PasskeyCheckedAt = passkeyCheckedAt.Time session.Metadata = metadata diff --git a/internal/query/sessions_test.go b/internal/query/sessions_test.go index 03a5b2197..38662ead7 100644 --- a/internal/query/sessions_test.go +++ b/internal/query/sessions_test.go @@ -17,43 +17,47 @@ import ( ) var ( - expectedSessionQuery = regexp.QuoteMeta(`SELECT projections.sessions1.id,` + - ` projections.sessions1.creation_date,` + - ` projections.sessions1.change_date,` + - ` projections.sessions1.sequence,` + - ` projections.sessions1.state,` + - ` projections.sessions1.resource_owner,` + - ` projections.sessions1.creator,` + - ` projections.sessions1.user_id,` + - ` projections.sessions1.user_checked_at,` + + expectedSessionQuery = regexp.QuoteMeta(`SELECT projections.sessions3.id,` + + ` projections.sessions3.creation_date,` + + ` projections.sessions3.change_date,` + + ` projections.sessions3.sequence,` + + ` projections.sessions3.state,` + + ` projections.sessions3.resource_owner,` + + ` projections.sessions3.creator,` + + ` projections.sessions3.domain,` + + ` projections.sessions3.user_id,` + + ` projections.sessions3.user_checked_at,` + ` projections.login_names2.login_name,` + ` projections.users8_humans.display_name,` + - ` projections.sessions1.password_checked_at,` + - ` projections.sessions1.passkey_checked_at,` + - ` projections.sessions1.metadata,` + - ` projections.sessions1.token_id` + - ` FROM projections.sessions1` + - ` LEFT JOIN projections.login_names2 ON projections.sessions1.user_id = projections.login_names2.user_id AND projections.sessions1.instance_id = projections.login_names2.instance_id` + - ` LEFT JOIN projections.users8_humans ON projections.sessions1.user_id = projections.users8_humans.user_id AND projections.sessions1.instance_id = projections.users8_humans.instance_id` + + ` projections.sessions3.password_checked_at,` + + ` projections.sessions3.intent_checked_at,` + + ` projections.sessions3.passkey_checked_at,` + + ` projections.sessions3.metadata,` + + ` projections.sessions3.token_id` + + ` FROM projections.sessions3` + + ` LEFT JOIN projections.login_names2 ON projections.sessions3.user_id = projections.login_names2.user_id AND projections.sessions3.instance_id = projections.login_names2.instance_id` + + ` LEFT JOIN projections.users8_humans ON projections.sessions3.user_id = projections.users8_humans.user_id AND projections.sessions3.instance_id = projections.users8_humans.instance_id` + ` AS OF SYSTEM TIME '-1 ms'`) - expectedSessionsQuery = regexp.QuoteMeta(`SELECT projections.sessions1.id,` + - ` projections.sessions1.creation_date,` + - ` projections.sessions1.change_date,` + - ` projections.sessions1.sequence,` + - ` projections.sessions1.state,` + - ` projections.sessions1.resource_owner,` + - ` projections.sessions1.creator,` + - ` projections.sessions1.user_id,` + - ` projections.sessions1.user_checked_at,` + + expectedSessionsQuery = regexp.QuoteMeta(`SELECT projections.sessions3.id,` + + ` projections.sessions3.creation_date,` + + ` projections.sessions3.change_date,` + + ` projections.sessions3.sequence,` + + ` projections.sessions3.state,` + + ` projections.sessions3.resource_owner,` + + ` projections.sessions3.creator,` + + ` projections.sessions3.domain,` + + ` projections.sessions3.user_id,` + + ` projections.sessions3.user_checked_at,` + ` projections.login_names2.login_name,` + ` projections.users8_humans.display_name,` + - ` projections.sessions1.password_checked_at,` + - ` projections.sessions1.passkey_checked_at,` + - ` projections.sessions1.metadata,` + + ` projections.sessions3.password_checked_at,` + + ` projections.sessions3.intent_checked_at,` + + ` projections.sessions3.passkey_checked_at,` + + ` projections.sessions3.metadata,` + ` COUNT(*) OVER ()` + - ` FROM projections.sessions1` + - ` LEFT JOIN projections.login_names2 ON projections.sessions1.user_id = projections.login_names2.user_id AND projections.sessions1.instance_id = projections.login_names2.instance_id` + - ` LEFT JOIN projections.users8_humans ON projections.sessions1.user_id = projections.users8_humans.user_id AND projections.sessions1.instance_id = projections.users8_humans.instance_id` + + ` FROM projections.sessions3` + + ` LEFT JOIN projections.login_names2 ON projections.sessions3.user_id = projections.login_names2.user_id AND projections.sessions3.instance_id = projections.login_names2.instance_id` + + ` LEFT JOIN projections.users8_humans ON projections.sessions3.user_id = projections.users8_humans.user_id AND projections.sessions3.instance_id = projections.users8_humans.instance_id` + ` AS OF SYSTEM TIME '-1 ms'`) sessionCols = []string{ @@ -64,11 +68,13 @@ var ( "state", "resource_owner", "creator", + "domain", "user_id", "user_checked_at", "login_name", "display_name", "password_checked_at", + "intent_checked_at", "passkey_checked_at", "metadata", "token", @@ -82,11 +88,13 @@ var ( "state", "resource_owner", "creator", + "domain", "user_id", "user_checked_at", "login_name", "display_name", "password_checked_at", + "intent_checked_at", "passkey_checked_at", "metadata", "count", @@ -132,12 +140,14 @@ func Test_SessionsPrepare(t *testing.T) { domain.SessionStateActive, "ro", "creator", + "domain", "user-id", testNow, "login-name", "display-name", testNow, testNow, + testNow, []byte(`{"key": "dmFsdWU="}`), }, }, @@ -156,6 +166,7 @@ func Test_SessionsPrepare(t *testing.T) { State: domain.SessionStateActive, ResourceOwner: "ro", Creator: "creator", + Domain: "domain", UserFactor: SessionUserFactor{ UserID: "user-id", UserCheckedAt: testNow, @@ -165,6 +176,9 @@ func Test_SessionsPrepare(t *testing.T) { PasswordFactor: SessionPasswordFactor{ PasswordCheckedAt: testNow, }, + IntentFactor: SessionIntentFactor{ + IntentCheckedAt: testNow, + }, PasskeyFactor: SessionPasskeyFactor{ PasskeyCheckedAt: testNow, }, @@ -191,12 +205,14 @@ func Test_SessionsPrepare(t *testing.T) { domain.SessionStateActive, "ro", "creator", + "domain", "user-id", testNow, "login-name", "display-name", testNow, testNow, + testNow, []byte(`{"key": "dmFsdWU="}`), }, { @@ -207,12 +223,14 @@ func Test_SessionsPrepare(t *testing.T) { domain.SessionStateActive, "ro", "creator2", + "domain", "user-id2", testNow, "login-name2", "display-name2", testNow, testNow, + testNow, []byte(`{"key": "dmFsdWU="}`), }, }, @@ -231,6 +249,7 @@ func Test_SessionsPrepare(t *testing.T) { State: domain.SessionStateActive, ResourceOwner: "ro", Creator: "creator", + Domain: "domain", UserFactor: SessionUserFactor{ UserID: "user-id", UserCheckedAt: testNow, @@ -240,6 +259,9 @@ func Test_SessionsPrepare(t *testing.T) { PasswordFactor: SessionPasswordFactor{ PasswordCheckedAt: testNow, }, + IntentFactor: SessionIntentFactor{ + IntentCheckedAt: testNow, + }, PasskeyFactor: SessionPasskeyFactor{ PasskeyCheckedAt: testNow, }, @@ -255,6 +277,7 @@ func Test_SessionsPrepare(t *testing.T) { State: domain.SessionStateActive, ResourceOwner: "ro", Creator: "creator2", + Domain: "domain", UserFactor: SessionUserFactor{ UserID: "user-id2", UserCheckedAt: testNow, @@ -264,6 +287,9 @@ func Test_SessionsPrepare(t *testing.T) { PasswordFactor: SessionPasswordFactor{ PasswordCheckedAt: testNow, }, + IntentFactor: SessionIntentFactor{ + IntentCheckedAt: testNow, + }, PasskeyFactor: SessionPasskeyFactor{ PasskeyCheckedAt: testNow, }, @@ -343,12 +369,14 @@ func Test_SessionPrepare(t *testing.T) { domain.SessionStateActive, "ro", "creator", + "domain", "user-id", testNow, "login-name", "display-name", testNow, testNow, + testNow, []byte(`{"key": "dmFsdWU="}`), "tokenID", }, @@ -362,6 +390,7 @@ func Test_SessionPrepare(t *testing.T) { State: domain.SessionStateActive, ResourceOwner: "ro", Creator: "creator", + Domain: "domain", UserFactor: SessionUserFactor{ UserID: "user-id", UserCheckedAt: testNow, @@ -371,6 +400,9 @@ func Test_SessionPrepare(t *testing.T) { PasswordFactor: SessionPasswordFactor{ PasswordCheckedAt: testNow, }, + IntentFactor: SessionIntentFactor{ + IntentCheckedAt: testNow, + }, PasskeyFactor: SessionPasskeyFactor{ PasskeyCheckedAt: testNow, }, diff --git a/internal/query/user_auth_method.go b/internal/query/user_auth_method.go index 0321a8750..dde1a5a38 100644 --- a/internal/query/user_auth_method.go +++ b/internal/query/user_auth_method.go @@ -6,6 +6,7 @@ import ( "time" sq "github.com/Masterminds/squirrel" + "github.com/zitadel/logging" "github.com/zitadel/zitadel/internal/api/authz" "github.com/zitadel/zitadel/internal/api/call" @@ -64,12 +65,27 @@ var ( name: projection.UserAuthMethodOwnerRemovedCol, table: userAuthMethodTable, } + + authMethodTypeTable = userAuthMethodTable.setAlias("auth_method_types") + authMethodTypeUserID = UserAuthMethodColumnUserID.setTable(authMethodTypeTable) + authMethodTypeInstanceID = UserAuthMethodColumnInstanceID.setTable(authMethodTypeTable) + authMethodTypeTypes = UserAuthMethodColumnMethodType.setTable(authMethodTypeTable) + authMethodTypeState = UserAuthMethodColumnState.setTable(authMethodTypeTable) + + userIDPsCountTable = idpUserLinkTable.setAlias("user_idps_count") + userIDPsCountUserID = IDPUserLinkUserIDCol.setTable(userIDPsCountTable) + userIDPsCountInstanceID = IDPUserLinkInstanceIDCol.setTable(userIDPsCountTable) + userIDPsCountCount = Column{ + name: "count", + table: userIDPsCountTable, + } ) type AuthMethods struct { SearchResponse AuthMethods []*AuthMethod } + type AuthMethod struct { UserID string CreationDate time.Time @@ -83,6 +99,11 @@ type AuthMethod struct { Type domain.UserAuthMethodType } +type AuthMethodTypes struct { + SearchResponse + AuthMethodTypes []domain.UserAuthMethodType +} + type UserAuthMethodSearchQueries struct { SearchRequest Queries []SearchQuery @@ -114,6 +135,41 @@ func (q *Queries) SearchUserAuthMethods(ctx context.Context, queries *UserAuthMe return userAuthMethods, err } +func (q *Queries) ListActiveUserAuthMethodTypes(ctx context.Context, userID string, withOwnerRemoved bool) (userAuthMethodTypes *AuthMethodTypes, err error) { + ctxData := authz.GetCtxData(ctx) + if ctxData.UserID != userID { + if err := q.checkPermission(ctx, domain.PermissionUserRead, ctxData.OrgID, userID); err != nil { + return nil, err + } + } + ctx, span := tracing.NewSpan(ctx) + defer func() { span.EndWithError(err) }() + + query, scan := prepareActiveUserAuthMethodTypesQuery(ctx, q.client) + eq := sq.Eq{ + UserIDCol.identifier(): userID, + UserInstanceIDCol.identifier(): authz.GetInstance(ctx).InstanceID(), + } + if !withOwnerRemoved { + eq[UserOwnerRemovedCol.identifier()] = false + } + stmt, args, err := query.Where(eq).ToSql() + if err != nil { + return nil, errors.ThrowInvalidArgument(err, "QUERY-Sfdrg", "Errors.Query.InvalidRequest") + } + + rows, err := q.client.QueryContext(ctx, stmt, args...) + if err != nil || rows.Err() != nil { + return nil, errors.ThrowInternal(err, "QUERY-SDgr3", "Errors.Internal") + } + userAuthMethodTypes, err = scan(rows) + if err != nil { + return nil, err + } + userAuthMethodTypes.LatestSequence, err = q.latestSequence(ctx, userTable, notifyTable, userAuthMethodTable, idpUserLinkTable) + return userAuthMethodTypes, err +} + func NewUserAuthMethodUserIDSearchQuery(value string) (SearchQuery, error) { return NewTextQuery(UserAuthMethodColumnUserID, value, TextEquals) } @@ -253,3 +309,80 @@ func prepareUserAuthMethodsQuery(ctx context.Context, db prepareDatabase) (sq.Se }, nil } } + +func prepareActiveUserAuthMethodTypesQuery(ctx context.Context, db prepareDatabase) (sq.SelectBuilder, func(*sql.Rows) (*AuthMethodTypes, error)) { + authMethodsQuery, authMethodsArgs, err := sq.Select( + "DISTINCT("+authMethodTypeTypes.identifier()+")", + authMethodTypeUserID.identifier(), + authMethodTypeInstanceID.identifier()). + From(authMethodTypeTable.identifier()). + Where(sq.Eq{authMethodTypeState.identifier(): domain.MFAStateReady}). + ToSql() + if err != nil { + return sq.SelectBuilder{}, nil + } + idpsQuery, _, err := sq.Select( + userIDPsCountUserID.identifier(), + userIDPsCountInstanceID.identifier(), + "COUNT("+userIDPsCountUserID.identifier()+") AS "+userIDPsCountCount.name). + From(userIDPsCountTable.identifier()). + GroupBy( + userIDPsCountUserID.identifier(), + userIDPsCountInstanceID.identifier(), + ). + ToSql() + if err != nil { + return sq.SelectBuilder{}, nil + } + return sq.Select( + NotifyPasswordSetCol.identifier(), + authMethodTypeTypes.identifier(), + userIDPsCountCount.identifier()). + From(userTable.identifier()). + LeftJoin(join(NotifyUserIDCol, UserIDCol)). + LeftJoin("("+authMethodsQuery+") AS "+authMethodTypeTable.alias+" ON "+ + authMethodTypeUserID.identifier()+" = "+UserIDCol.identifier()+" AND "+ + authMethodTypeInstanceID.identifier()+" = "+UserInstanceIDCol.identifier(), + authMethodsArgs...). + LeftJoin("(" + idpsQuery + ") AS " + userIDPsCountTable.alias + " ON " + + userIDPsCountUserID.identifier() + " = " + UserIDCol.identifier() + " AND " + + userIDPsCountInstanceID.identifier() + " = " + UserInstanceIDCol.identifier() + db.Timetravel(call.Took(ctx))). + PlaceholderFormat(sq.Dollar), + func(rows *sql.Rows) (*AuthMethodTypes, error) { + userAuthMethodTypes := make([]domain.UserAuthMethodType, 0) + var passwordSet sql.NullBool + var idp sql.NullInt64 + for rows.Next() { + var authMethodType sql.NullInt16 + err := rows.Scan( + &passwordSet, + &authMethodType, + &idp, + ) + if err != nil { + return nil, err + } + if authMethodType.Valid { + userAuthMethodTypes = append(userAuthMethodTypes, domain.UserAuthMethodType(authMethodType.Int16)) + } + } + if passwordSet.Valid && passwordSet.Bool { + userAuthMethodTypes = append(userAuthMethodTypes, domain.UserAuthMethodTypePassword) + } + if idp.Valid && idp.Int64 > 0 { + logging.Error("IDP", idp.Int64) + userAuthMethodTypes = append(userAuthMethodTypes, domain.UserAuthMethodTypeIDP) + } + + if err := rows.Close(); err != nil { + return nil, errors.ThrowInternal(err, "QUERY-3n9fl", "Errors.Query.CloseRows") + } + + return &AuthMethodTypes{ + AuthMethodTypes: userAuthMethodTypes, + SearchResponse: SearchResponse{ + Count: uint64(len(userAuthMethodTypes)), + }, + }, nil + } +} diff --git a/internal/query/user_auth_method_test.go b/internal/query/user_auth_method_test.go index b09d6c9e7..da86a02aa 100644 --- a/internal/query/user_auth_method_test.go +++ b/internal/query/user_auth_method_test.go @@ -36,6 +36,23 @@ var ( "method_type", "count", } + prepareActiveAuthMethodTypesStmt = `SELECT projections.users8_notifications.password_set,` + + ` auth_method_types.method_type,` + + ` user_idps_count.count` + + ` FROM projections.users8` + + ` LEFT JOIN projections.users8_notifications ON projections.users8.id = projections.users8_notifications.user_id AND projections.users8.instance_id = projections.users8_notifications.instance_id` + + ` LEFT JOIN (SELECT DISTINCT(auth_method_types.method_type), auth_method_types.user_id, auth_method_types.instance_id FROM projections.user_auth_methods4 AS auth_method_types` + + ` WHERE auth_method_types.state = $1) AS auth_method_types` + + ` ON auth_method_types.user_id = projections.users8.id AND auth_method_types.instance_id = projections.users8.instance_id` + + ` LEFT JOIN (SELECT user_idps_count.user_id, user_idps_count.instance_id, COUNT(user_idps_count.user_id) AS count FROM projections.idp_user_links3 AS user_idps_count` + + ` GROUP BY user_idps_count.user_id, user_idps_count.instance_id) AS user_idps_count` + + ` ON user_idps_count.user_id = projections.users8.id AND user_idps_count.instance_id = projections.users8.instance_id` + + ` AS OF SYSTEM TIME '-1 ms` + prepareActiveAuthMethodTypesCols = []string{ + "password_set", + "method_type", + "idps_count", + } ) func Test_UserAuthMethodPrepares(t *testing.T) { @@ -182,6 +199,95 @@ func Test_UserAuthMethodPrepares(t *testing.T) { }, object: nil, }, + { + name: "prepareActiveUserAuthMethodTypesQuery no result", + prepare: prepareActiveUserAuthMethodTypesQuery, + want: want{ + sqlExpectations: mockQueries( + regexp.QuoteMeta(prepareActiveAuthMethodTypesStmt), + nil, + nil, + ), + }, + object: &AuthMethodTypes{AuthMethodTypes: []domain.UserAuthMethodType{}}, + }, + { + name: "prepareActiveUserAuthMethodTypesQuery one second factor", + prepare: prepareActiveUserAuthMethodTypesQuery, + want: want{ + sqlExpectations: mockQueries( + regexp.QuoteMeta(prepareActiveAuthMethodTypesStmt), + prepareActiveAuthMethodTypesCols, + [][]driver.Value{ + { + true, + domain.UserAuthMethodTypePasswordless, + 1, + }, + }, + ), + }, + object: &AuthMethodTypes{ + SearchResponse: SearchResponse{ + Count: 3, + }, + AuthMethodTypes: []domain.UserAuthMethodType{ + domain.UserAuthMethodTypePasswordless, + domain.UserAuthMethodTypePassword, + domain.UserAuthMethodTypeIDP, + }, + }, + }, + { + name: "prepareActiveUserAuthMethodTypesQuery multiple second factors", + prepare: prepareActiveUserAuthMethodTypesQuery, + want: want{ + sqlExpectations: mockQueries( + regexp.QuoteMeta(prepareActiveAuthMethodTypesStmt), + prepareActiveAuthMethodTypesCols, + [][]driver.Value{ + { + true, + domain.UserAuthMethodTypePasswordless, + 1, + }, + { + true, + domain.UserAuthMethodTypeOTP, + 1, + }, + }, + ), + }, + object: &AuthMethodTypes{ + SearchResponse: SearchResponse{ + Count: 4, + }, + AuthMethodTypes: []domain.UserAuthMethodType{ + domain.UserAuthMethodTypePasswordless, + domain.UserAuthMethodTypeOTP, + domain.UserAuthMethodTypePassword, + domain.UserAuthMethodTypeIDP, + }, + }, + }, + { + name: "prepareActiveUserAuthMethodTypesQuery sql err", + prepare: prepareActiveUserAuthMethodTypesQuery, + want: want{ + sqlExpectations: mockQueryErr( + regexp.QuoteMeta(prepareActiveAuthMethodTypesStmt), + sql.ErrConnDone, + ), + err: func(err error) (error, bool) { + if !errors.Is(err, sql.ErrConnDone) { + return fmt.Errorf("err should be sql.ErrConnDone got: %w", err), false + } + return nil, true + }, + }, + object: nil, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/internal/repository/idpintent/intent.go b/internal/repository/idpintent/intent.go index eea0bf68f..fe26c9dfa 100644 --- a/internal/repository/idpintent/intent.go +++ b/internal/repository/idpintent/intent.go @@ -69,6 +69,8 @@ type SucceededEvent struct { eventstore.BaseEvent `json:"-"` IDPUser []byte `json:"idpUser"` + IDPUserID string `json:"idpUserId,omitempty"` + IDPUserName string `json:"idpUserName,omitempty"` UserID string `json:"userId,omitempty"` IDPAccessToken *crypto.CryptoValue `json:"idpAccessToken,omitempty"` IDPIDToken string `json:"idpIdToken,omitempty"` @@ -78,10 +80,12 @@ func NewSucceededEvent( ctx context.Context, aggregate *eventstore.Aggregate, idpUser []byte, + idpUserID, + idpUserName, userID string, idpAccessToken *crypto.CryptoValue, idpIDToken string, -) (*SucceededEvent, error) { +) *SucceededEvent { return &SucceededEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, @@ -89,10 +93,12 @@ func NewSucceededEvent( SucceededEventType, ), IDPUser: idpUser, + IDPUserID: idpUserID, + IDPUserName: idpUserName, UserID: userID, IDPAccessToken: idpAccessToken, IDPIDToken: idpIDToken, - }, nil + } } func (e *SucceededEvent) Data() interface{} { diff --git a/internal/repository/session/eventstore.go b/internal/repository/session/eventstore.go index 3253cc856..07f458586 100644 --- a/internal/repository/session/eventstore.go +++ b/internal/repository/session/eventstore.go @@ -6,6 +6,7 @@ func RegisterEventMappers(es *eventstore.Eventstore) { es.RegisterFilterEventMapper(AggregateType, AddedType, AddedEventMapper). RegisterFilterEventMapper(AggregateType, UserCheckedType, UserCheckedEventMapper). RegisterFilterEventMapper(AggregateType, PasswordCheckedType, PasswordCheckedEventMapper). + RegisterFilterEventMapper(AggregateType, IntentCheckedType, IntentCheckedEventMapper). RegisterFilterEventMapper(AggregateType, PasskeyChallengedType, eventstore.GenericEventMapper[PasskeyChallengedEvent]). RegisterFilterEventMapper(AggregateType, PasskeyCheckedType, eventstore.GenericEventMapper[PasskeyCheckedEvent]). RegisterFilterEventMapper(AggregateType, TokenSetType, TokenSetEventMapper). diff --git a/internal/repository/session/session.go b/internal/repository/session/session.go index 887f056e8..9b48543ec 100644 --- a/internal/repository/session/session.go +++ b/internal/repository/session/session.go @@ -16,6 +16,7 @@ const ( AddedType = sessionEventPrefix + "added" UserCheckedType = sessionEventPrefix + "user.checked" PasswordCheckedType = sessionEventPrefix + "password.checked" + IntentCheckedType = sessionEventPrefix + "intent.checked" PasskeyChallengedType = sessionEventPrefix + "passkey.challenged" PasskeyCheckedType = sessionEventPrefix + "passkey.checked" TokenSetType = sessionEventPrefix + "token.set" @@ -25,6 +26,8 @@ const ( type AddedEvent struct { eventstore.BaseEvent `json:"-"` + + Domain string `json:"domain,omitempty"` } func (e *AddedEvent) Data() interface{} { @@ -37,6 +40,7 @@ func (e *AddedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint { func NewAddedEvent(ctx context.Context, aggregate *eventstore.Aggregate, + domain string, ) *AddedEvent { return &AddedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( @@ -44,6 +48,7 @@ func NewAddedEvent(ctx context.Context, aggregate, AddedType, ), + Domain: domain, } } @@ -144,6 +149,47 @@ func PasswordCheckedEventMapper(event *repository.Event) (eventstore.Event, erro return added, nil } +type IntentCheckedEvent struct { + eventstore.BaseEvent `json:"-"` + + CheckedAt time.Time `json:"checkedAt"` +} + +func (e *IntentCheckedEvent) Data() interface{} { + return e +} + +func (e *IntentCheckedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint { + return nil +} + +func NewIntentCheckedEvent( + ctx context.Context, + aggregate *eventstore.Aggregate, + checkedAt time.Time, +) *IntentCheckedEvent { + return &IntentCheckedEvent{ + BaseEvent: *eventstore.NewBaseEventForPush( + ctx, + aggregate, + IntentCheckedType, + ), + CheckedAt: checkedAt, + } +} + +func IntentCheckedEventMapper(event *repository.Event) (eventstore.Event, error) { + added := &IntentCheckedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + } + err := json.Unmarshal(event.Data, added) + if err != nil { + return nil, errors.ThrowInternal(err, "SESSION-DGt90", "unable to unmarshal intent checked") + } + + return added, nil +} + type PasskeyChallengedEvent struct { eventstore.BaseEvent `json:"-"` diff --git a/internal/repository/user/human_mfa_passwordless.go b/internal/repository/user/human_mfa_passwordless.go index f5e68b639..1ffa14af3 100644 --- a/internal/repository/user/human_mfa_passwordless.go +++ b/internal/repository/user/human_mfa_passwordless.go @@ -39,6 +39,7 @@ func NewHumanPasswordlessAddedEvent( aggregate *eventstore.Aggregate, webAuthNTokenID, challenge string, + rpID string, ) *HumanPasswordlessAddedEvent { return &HumanPasswordlessAddedEvent{ HumanWebAuthNAddedEvent: *NewHumanWebAuthNAddedEvent( @@ -49,6 +50,7 @@ func NewHumanPasswordlessAddedEvent( ), webAuthNTokenID, challenge, + rpID, ), } } diff --git a/internal/repository/user/human_mfa_u2f.go b/internal/repository/user/human_mfa_u2f.go index 27fe6be3f..096026b87 100644 --- a/internal/repository/user/human_mfa_u2f.go +++ b/internal/repository/user/human_mfa_u2f.go @@ -28,6 +28,7 @@ func NewHumanU2FAddedEvent( aggregate *eventstore.Aggregate, webAuthNTokenID, challenge string, + rpID string, ) *HumanU2FAddedEvent { return &HumanU2FAddedEvent{ HumanWebAuthNAddedEvent: *NewHumanWebAuthNAddedEvent( @@ -38,6 +39,7 @@ func NewHumanU2FAddedEvent( ), webAuthNTokenID, challenge, + rpID, ), } } diff --git a/internal/repository/user/human_mfa_web_auth_n.go b/internal/repository/user/human_mfa_web_auth_n.go index faeb3124c..77f27fb64 100644 --- a/internal/repository/user/human_mfa_web_auth_n.go +++ b/internal/repository/user/human_mfa_web_auth_n.go @@ -14,6 +14,7 @@ type HumanWebAuthNAddedEvent struct { WebAuthNTokenID string `json:"webAuthNTokenId"` Challenge string `json:"challenge"` + RPID string `json:"rpID,omitempty"` } func (e *HumanWebAuthNAddedEvent) Data() interface{} { @@ -28,11 +29,13 @@ func NewHumanWebAuthNAddedEvent( base *eventstore.BaseEvent, webAuthNTokenID, challenge string, + rpID string, ) *HumanWebAuthNAddedEvent { return &HumanWebAuthNAddedEvent{ BaseEvent: *base, WebAuthNTokenID: webAuthNTokenID, Challenge: challenge, + RPID: rpID, } } diff --git a/internal/repository/user/human_password.go b/internal/repository/user/human_password.go index 26343d664..ccd38527d 100644 --- a/internal/repository/user/human_password.go +++ b/internal/repository/user/human_password.go @@ -76,6 +76,8 @@ type HumanPasswordCodeAddedEvent struct { Code *crypto.CryptoValue `json:"code,omitempty"` Expiry time.Duration `json:"expiry,omitempty"` NotificationType domain.NotificationType `json:"notificationType,omitempty"` + URLTemplate string `json:"url_template,omitempty"` + CodeReturned bool `json:"code_returned,omitempty"` } func (e *HumanPasswordCodeAddedEvent) Data() interface{} { @@ -92,6 +94,18 @@ func NewHumanPasswordCodeAddedEvent( code *crypto.CryptoValue, expiry time.Duration, notificationType domain.NotificationType, +) *HumanPasswordCodeAddedEvent { + return NewHumanPasswordCodeAddedEventV2(ctx, aggregate, code, expiry, notificationType, "", false) +} + +func NewHumanPasswordCodeAddedEventV2( + ctx context.Context, + aggregate *eventstore.Aggregate, + code *crypto.CryptoValue, + expiry time.Duration, + notificationType domain.NotificationType, + urlTemplate string, + codeReturned bool, ) *HumanPasswordCodeAddedEvent { return &HumanPasswordCodeAddedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( @@ -102,6 +116,8 @@ func NewHumanPasswordCodeAddedEvent( Code: code, Expiry: expiry, NotificationType: notificationType, + URLTemplate: urlTemplate, + CodeReturned: codeReturned, } } diff --git a/internal/static/i18n/bg.yaml b/internal/static/i18n/bg.yaml new file mode 100644 index 000000000..695007888 --- /dev/null +++ b/internal/static/i18n/bg.yaml @@ -0,0 +1,1240 @@ +Errors: + Internal: Възникна вътрешна грешка + NoChangesFound: Без промени + OriginNotAllowed: Този "Произход" не е разрешен + IDMissing: Липсва лична карта + ResourceOwnerMissing: Липсва организация на собственика на ресурса + RemoveFailed: Не можа да бъде премахнат + ProjectionName: + Invalid: Невалидно име на проекцията + Assets: + EmptyKey: Ключът на актива е празен + Store: + NotInitialized: Съхранението на активи не е инициализирано + NotConfigured: Съхранението на активи не е конфигурирано + Bucket: + Internal: Вътрешна грешка при създаване на контейнер + AlreadyExists: Кофата вече съществува + CreateFailed: Кофата не е създадена + ListFailed: Кофите не могат да бъдат прочетени + RemoveFailed: Кофата не е изтрита + SetPublicFailed: Кофата не можа да се зададе като публична + Object: + PutFailed: Обектът не е създаден + GetFailed: Обектът не можа да бъде прочетен + NotFound: Обектът не може да бъде намерен + PresignedTokenFailed: Подписаният токен не можа да бъде създаден + ListFailed: Списъкът с обекти не можа да бъде прочетен + RemoveFailed: Обектът не можа да бъде премахнат + Limit: + ExceedsDefault: Лимитът надвишава лимита по подразбиране + Language: + NotParsed: Езикът не можа да бъде анализиран синтактично + OIDCSettings: + NotFound: Конфигурацията на OIDC не е намерена + AlreadyExists: OIDC конфигурацията вече съществува + SecretGenerator: + AlreadyExists: Таен генератор вече съществува + TypeMissing: Липсва тип таен генератор + NotFound: Тайният генератор не е намерен + SMSConfig: + NotFound: SMS конфигурацията не е намерена + AlreadyActive: SMS конфигурацията вече е активна + AlreadyDeactivated: SMS конфигурацията вече е деактивирана + SMTPConfig: + NotFound: SMTP конфигурацията не е намерена + AlreadyExists: SMTP конфигурация вече съществува + SenderAdressNotCustomDomain: >- + Адресът на изпращача трябва да бъде конфигуриран като персонализиран + домейн в екземпляра. + Notification: + NoDomain: Няма намерен домейн за съобщение + User: + NotFound: Потребителят не може да бъде намерен + AlreadyExists: Вече съществува потребител + NotFoundOnOrg: Потребителят не може да бъде намерен в избраната организация + NotAllowedOrg: Потребителят не е член на необходимата организация + UserIDMissing: Липсва потребителско име + UserIDWrong: Потребителят на заявката не е равен на удостоверения потребител + DomainPolicyNil: Правилата на организацията са празни + EmailAsUsernameNotAllowed: Имейлът не е разрешен като потребителско име + Invalid: Потребителските данни са невалидни + DomainNotAllowedAsUsername: Домейнът вече е резервиран и не може да се използва + AlreadyInactive: Потребителят вече е неактивен + NotInactive: Потребителят не е неактивен + CantDeactivateInitial: 'Потребител с начално състояние може да бъде изтрит, но не и деактивиран' + ShouldBeActiveOrInitial: Потребителят не е активен или начален + AlreadyInitialised: Потребителят вече е инициализиран + NotInitialised: Потребителят все още не е инициализиран + NotLocked: Потребителят не е заключен + NoChanges: Няма намерени промени + InitCodeNotFound: Кодът за инициализиране не е намерен + UsernameNotChanged: Потребителското име не е променено + InvalidURLTemplate: URL шаблонът е невалиден + Profile: + NotFound: Профилът не е намерен + NotChanged: Профилът не е променен + Empty: Профилът е празен + FirstNameEmpty: Първото име в профила е празно + LastNameEmpty: Фамилията в профила е празна + IDMissing: Липсва ID на потребителския профил + Email: + NotFound: Имейлът не е намерен + Invalid: Имейлът е невалиден + AlreadyVerified: Имейлът вече е потвърден + NotChanged: Имейлът не е променен + Empty: Имейлът е празен + IDMissing: Имейл ID липсва + Phone: + NotFound: Телефонът не е намерен + Invalid: Телефонът е невалиден + AlreadyVerified: Телефонът вече е потвърден + Empty: Телефонът е празен + NotChanged: Телефонът не е сменен + Address: + NotFound: Адресът не е намерен + NotChanged: Адресът не е променен + Machine: + Key: + NotFound: Машинният ключ не е намерен + AlreadyExisting: Машинният ключ вече съществува + Secret: + NotExisting: Тайната не съществува + Invalid: Тайната е невалидна + CouldNotGenerate: Тайната не можа да бъде генерирана + PAT: + NotFound: Личен токен за достъп не е намерен + NotHuman: Потребителят трябва да е личен + NotMachine: Потребителят трябва да е техничен + WrongType: Не е разрешено за този тип потребител + NotAllowedToLink: Потребителят няма право да се свързва с външен доставчик на данни за вход + Username: + AlreadyExists: Потребителско име вече е заето + Reserved: Потребителско име вече е заето + Empty: Потребителското име е празно + Code: + Empty: Кодът е празен + NotFound: Кодът не е намерен + Expired: Кодът е изтекъл + GeneratorAlgNotSupported: Неподдържан генераторен алгоритъм + Password: + NotFound: Паролата не е намерена + Empty: Паролата е празна + Invalid: Паролата е невалидна + NotSet: Потребителят не е задал парола + PasswordComplexityPolicy: + NotFound: Политиката за парола не е намерена + MinLength: Паролата е твърде кратка + MinLengthNotAllowed: Дадена минимална дължина не е разрешена + HasLower: Паролата трябва да съдържа малки букви + HasUpper: Паролата трябва да съдържа главни букви + HasNumber: Паролата трябва да съдържа число + HasSymbol: Паролата трябва да съдържа символ + ExternalIDP: + Invalid: Невалиден външен IDP + IDPConfigNotExisting: Невалиден доставчик на IDP за тази организация + NotAllowed: Външен IDP не е разрешен в тази организация + MinimumExternalIDPNeeded: Трябва да се добави поне един IDP + AlreadyExists: Външен IDP вече е зает + NotFound: Външен IDP не е намерен + MFA: + OTP: + AlreadyReady: Многофакторният OTP (OneTimePassword) вече е настроен + NotExisting: Многофакторният OTP (OneTimePassword) не съществува + NotReady: Многофакторният OTP (OneTimePassword) не е готов + InvalidCode: Невалиден код + U2F: + NotExisting: U2F не съществува + Passwordless: + NotExisting: Без парола не съществува + WebAuthN: + NotFound: WebAuthN Token не можа да бъде намерен + BeginRegisterFailed: Неуспешна регистрация за стартиране на WebAuthN + MarshalError: Грешка в маршалските данни + ErrorOnParseCredential: Грешка при анализа на идентификационните данни + CreateCredentialFailed: Грешка при създаване на идентификационни данни + BeginLoginFailed: Началото на влизането в WebAuthN не бе успешно + ValidateLoginFailed: Грешка при потвърждаване на идентификационните данни за вход + CloneWarning: Идентификационните данни могат да бъдат клонирани + RefreshToken: + Invalid: Токенът за опресняване е невалиден + NotFound: Токенът за обновяване не е намерен + Instance: + NotFound: Екземплярът не е намерен + AlreadyExists: Екземплярът вече съществува + NotChanged: Екземплярът не е променен + Org: + AlreadyExists: Името на организацията вече е заето + Invalid: Организацията е невалидна + AlreadyDeactivated: Организацията вече е деактивирана + AlreadyActive: Организацията вече е активна + Empty: Организацията е празна + NotFound: Организацията не е намерена + NotChanged: Организацията не е променена + DefaultOrgNotDeletable: Организацията по подразбиране не трябва да се изтрива + ZitadelOrgNotDeletable: Организация с проект ZITADEL не трябва да се изтрива + InvalidDomain: Невалиден домейн + DomainMissing: Липсва домейн + DomainNotOnOrg: Домейнът не съществува в организацията + DomainNotVerified: Домейнът не е проверен + DomainAlreadyVerified: Домейнът вече е потвърден + DomainVerificationTypeInvalid: Типът проверка на домейна е невалиден + DomainVerificationMissing: Проверката на домейна все още не е започнала + DomainVerificationFailed: Неуспешна проверка на домейна + PrimaryDomainNotDeletable: Основният домейн не трябва да се изтрива + DomainNotFound: Домейнът не е намерен + MemberIDMissing: Липсва ID на член + MemberNotFound: Членът на организацията не е намерен + InvalidMember: Членът на организацията е невалиден + UserIDMissing: Липсва потребителско име + PolicyAlreadyExists: Политиката вече съществува + PolicyNotExisting: Политиката не съществува + IdpInvalid: IDP конфигурацията е невалидна + IdpNotExisting: IDP конфигурация не съществува + OIDCConfigInvalid: OIDC IDP конфигурацията е невалидна + IdpIsNotOIDC: IDP конфигурацията не е от тип oidc + Domain: + AlreadyExists: Домейнът вече съществува + InvalidCharacter: 'Само буквено-цифрови знаци, . ' + IDP: + InvalidSearchQuery: Невалидна заявка за търсене + LoginPolicy: + NotFound: Правилата за влизане не са намерени + Invalid: Правилата за влизане са невалидни + RedirectURIInvalid: URI адресът за пренасочване по подразбиране е невалиден + NotExisting: Политиката за влизане не съществува + AlreadyExists: Политиката за влизане вече съществува + IdpProviderAlreadyExisting: Вече съществува доставчик на самоличност + IdpProviderNotExisting: Доставчикът на самоличност не съществува + RegistrationNotAllowed: Регистрацията не е разрешена + UsernamePasswordNotAllowed: Влизането с потребителско име / парола не е разрешено + MFA: + AlreadyExists: Multifactor вече съществува + NotExisting: Мултифактор не съществува + Unspecified: Многофакторна невалидност + MailTemplate: + NotFound: Шаблонът за поща по подразбиране не е намерен + NotChanged: Шаблонът за поща по подразбиране не е променен + AlreadyExists: Шаблонът за поща по подразбиране вече съществува + Invalid: Шаблонът за имейл по подразбиране е невалиден + CustomMessageText: + NotFound: Текстът на съобщението по подразбиране не е намерен + NotChanged: Текстът на съобщението по подразбиране не е променен + AlreadyExists: Текстът на съобщението по подразбиране вече съществува + Invalid: Текстът на съобщението по подразбиране е невалиден + PasswordComplexityPolicy: + NotFound: Правилата за сложност на паролата не са намерени + Empty: Правилата за сложност на паролата са празни + NotExisting: Правилата за сложност на паролите не съществуват + AlreadyExists: Политиката за сложност на паролата вече съществува + PasswordLockoutPolicy: + NotFound: Правилата за блокиране на парола не са намерени + Empty: Правилата за блокиране на парола са празни + NotExisting: Правилата за блокиране на пароли не съществуват + AlreadyExists: Политиката за блокиране на парола вече съществува + PasswordAgePolicy: + NotFound: Правилата за възрастта на паролата не са намерени + Empty: Правилата за възрастта на паролата са празни + NotExisting: Правилата за възрастта на паролата не съществуват + AlreadyExists: Вече съществува политика за възрастта на паролата + OrgIAMPolicy: + Empty: Правилата за IAM на организацията са празни + NotExisting: IAM политиката на организацията не съществува + AlreadyExists: Политиката за IAM на организацията вече съществува + NotificationPolicy: + NotFound: Правилата за уведомяване не са намерени + NotChanged: Правилата за уведомяване не са променени + AlreadyExists: Политиката за уведомяване вече съществува + LabelPolicy: + NotFound: Правилата за лични етикети не са намерени + NotChanged: Политиката на частния етикет не е променена + Project: + ProjectIDMissing: Липсва ID на проекта + AlreadyExists: Проектът вече съществува в организацията + OrgNotExisting: Организацията не съществува + UserNotExisting: Потребителят не съществува + CouldNotGenerateClientSecret: Не можа да се генерира клиентска тайна + Invalid: Проектът е невалиден + NotActive: Проектът не е активен + NotInactive: Проектът не е деактивиран + NotFound: Проектът не е намерен + UserIDMissing: Липсва потребителско име + Member: + NotFound: Членът на проекта не е намерен + Invalid: Членът на проекта е невалиден + AlreadyExists: Член на проекта вече съществува + NotExisting: Член на проекта не съществува + MinimumOneRoleNeeded: Трябва да се добави поне една роля + Role: + AlreadyExists: Ролята вече съществува + Invalid: Ролята е невалидна + NotExisting: Ролята не съществува + IDMissing: Липсва лична карта + App: + AlreadyExists: Приложението вече съществува + NotFound: Приложението не е намерено + Invalid: Приложението е невалидно + NotExisting: Приложението не съществува + NotActive: Приложението не е активно + NotInactive: Приложението не е неактивно + OIDCConfigInvalid: OIDC конфигурацията е невалидна + APIConfigInvalid: API конфигурацията е невалидна + SAMLConfigInvalid: SAML конфигурацията е невалидна + IsNotOIDC: Приложението не е тип OIDC + IsNotAPI: Приложението не е тип API + IsNotSAML: Приложението не е тип SAML + SAMLMetadataMissing: Липсват SAML метаданни + SAMLMetadataFormat: Грешка във формата на SAML метаданни + SAMLEntityIDAlreadyExisting: SAML EntityID вече съществува + OIDCAuthMethodNoSecret: Избраният метод за удостоверяване на OIDC не изисква тайна + APIAuthMethodNoSecret: Избраният API Auth Method не изисква тайна + AuthMethodNoPrivateKeyJWT: Избраният метод за удостоверяване не изисква ключ + ClientSecretInvalid: Тайната на клиента е невалидна + Key: + AlreadyExisting: Вече съществува ключ за приложение + NotFound: Ключът на приложението не е намерен + RequiredFieldsMissing: Някои задължителни полета липсват + Grant: + AlreadyExists: Вече съществува субсидия за проекта + NotFound: Грантът не е намерен + Invalid: Грантът за проект е невалиден + NotExisting: Безвъзмездна помощ за проекта не съществува + HasNotExistingRole: Една роля не съществува в проекта + NotActive: Грантът по проекта не е активен + NotInactive: Грантът по проекта не е неактивен + IAM: + NotFound: Екземплярът не е намерен + Member: + RolesNotChanged: Ролите не са сменени + MemberInvalid: Членът е невалиден + MemberAlreadyExisting: Член вече съществува + MemberNotExisting: Членът не съществува + IDMissing: ID липсва + IAMProjectIDMissing: Липсва идентификатор на IAM проект + IamProjectAlreadySet: Идентификаторът на IAM проект вече е зададен + IdpInvalid: IDP конфигурацията е невалидна + IdpNotExisting: IDP конфигурация не съществува + OIDCConfigInvalid: OIDC IDP конфигурацията е невалидна + IdpIsNotOIDC: IDP конфигурацията не е от тип oidc + LoginPolicyInvalid: Правилата за влизане са невалидни + LoginPolicyNotExisting: Правилата за влизане не съществуват + IdpProviderInvalid: Доставчикът на самоличност е невалиден + LoginPolicy: + NotFound: Правилата за влизане по подразбиране не са намерени + NotChanged: Правилата за влизане по подразбиране не са променени + NotExisting: Политиката за влизане по подразбиране не съществува + AlreadyExists: Политиката за влизане по подразбиране вече съществува + RedirectURIInvalid: URI адресът за пренасочване по подразбиране е невалиден + MFA: + AlreadyExists: Multifactor вече съществува + NotExisting: Мултифактор не съществува + Unspecified: Многофакторна невалидност + IDP: + AlreadyExists: Доставчикът на самоличност вече съществува + NotExisting: Доставчикът на самоличност не съществува + Invalid: Доставчикът на самоличност е невалиден + IDPConfig: + AlreadyExists: Конфигурацията на доставчик на самоличност вече съществува + NotInactive: Конфигурацията на доставчик на самоличност не е неактивна + NotActive: Конфигурацията на доставчик на самоличност не е активна + LabelPolicy: + NotFound: Правилата за лични етикети по подразбиране не са намерени + NotChanged: Правилата за лични етикети по подразбиране не са променени + MailTemplate: + NotFound: Шаблонът за поща по подразбиране не е намерен + NotChanged: Шаблонът за поща по подразбиране не е променен + AlreadyExists: Шаблонът за поща по подразбиране вече съществува + Invalid: Шаблонът за имейл по подразбиране е невалиден + CustomMessageText: + NotFound: Текстът на съобщението по подразбиране не е намерен + NotChanged: Текстът на съобщението по подразбиране не е променен + AlreadyExists: Текстът на съобщението по подразбиране вече съществува + Invalid: Текстът на съобщението по подразбиране е невалиден + PasswordComplexityPolicy: + NotFound: Правилата за сложност на паролата по подразбиране не са намерени + NotExisting: Политиката за сложност на паролата по подразбиране не съществува + AlreadyExists: Политиката за сложност на паролата по подразбиране вече съществува + Empty: Правилата за сложност на паролата по подразбиране са празни + NotChanged: Правилата за сложност на паролата по подразбиране не са променени + PasswordAgePolicy: + NotFound: Правилата за възрастта на паролата по подразбиране не са намерени + NotExisting: Политиката за възрастта на паролата по подразбиране не съществува + AlreadyExists: Вече съществува стандартна политика за възрастта на паролата + Empty: Правилата за възрастта на паролата по подразбиране са празни + NotChanged: Правилата за възрастта на паролата по подразбиране не са променени + PasswordLockoutPolicy: + NotFound: Правилата за блокиране на парола по подразбиране не са намерени + NotExisting: Политиката за блокиране на парола по подразбиране не съществува + AlreadyExists: Политиката за блокиране на парола по подразбиране вече съществува + Empty: Правилата за блокиране на парола по подразбиране са празни + NotChanged: Правилата за блокиране на парола по подразбиране не са променени + DomainPolicy: + NotFound: IAM политиката на организацията не е намерена + Empty: Правилата за IAM на организацията са празни + NotExisting: IAM политиката на организацията не съществува + AlreadyExists: Политиката за IAM на организацията вече съществува + NotChanged: Политиката за IAM на организацията не е променена + NotificationPolicy: + NotFound: Правилата за уведомяване по подразбиране не са намерени + NotChanged: Правилата за уведомяване по подразбиране не са променени + AlreadyExists: Политиката за уведомяване по подразбиране вече съществува + Policy: + AlreadyExists: Политиката вече съществува + Label: + Invalid: + PrimaryColor: Основният цвят не е валидна стойност на шестнадесетичен цвят + BackgroundColor: Цветът на фона не е валидна шестнадесетична стойност на цвета + WarnColor: >- + Цветът на предупреждението не е валидна стойност на шестнадесетичен + цвят + FontColor: Цветът на шрифта не е валидна шестнадесетична стойност на цвета + PrimaryColorDark: >- + Основният цвят (тъмен режим) не е валидна стойност на шестнадесетичен + цвят + BackgroundColorDark: >- + Цветът на фона (тъмен режим) не е валидна стойност на шестнадесетичен + цвят + WarnColorDark: >- + Предупредителният цвят (тъмен режим) не е валидна стойност на + шестнадесетичен цвят + FontColorDark: >- + Цветът на шрифта (тъмен режим) не е валидна шестнадесетична цветова + стойност + UserGrant: + AlreadyExists: Потребителското разрешение вече съществува + NotFound: Потребителското разрешение не е намерено + Invalid: Потребителското разрешение е невалидно + NotChanged: Потребителското разрешение не е променено + IDMissing: ID липсва + NotActive: Потребителското разрешение не е активно + NotInactive: Предоставянето на потребител не е деактивирано + NoPermissionForProject: Потребителят няма разрешения за този проект + RoleKeyNotFound: Ролята не е намерена + Member: + AlreadyExists: Член вече съществува + IDPConfig: + AlreadyExists: IDP конфигурация с това име вече съществува + NotExisting: Конфигурацията на доставчик на самоличност не съществува + Changes: + NotFound: Няма намерена история + AuditRetention: Историята е извън съхранението на журнала за проверка + Token: + NotFound: Токенът не е намерен + UserSession: + NotFound: UserSession не е намерена + Key: + ExpireBeforeNow: Срокът на годност е в миналото + Login: + LoginPolicy: + MFA: + ForceAndNotConfigured: >- + Multifactor е конфигуриран според изискванията, но не са конфигурирани + възможни доставчици. + Step: + Started: + AlreadyExists: Започната стъпка вече съществува + Done: + AlreadyExists: Направената стъпка вече съществува + CustomText: + AlreadyExists: Персонализиран текст вече съществува + Invalid: Персонализираният текст е невалиден + NotFound: Персонализираният текст не е намерен + TranslationFile: + ReadError: Грешка при четене на файла за превод + MergeError: Файлът за превод не можа да бъде обединен с персонализирани преводи + NotFound: Файлът за превод не съществува + Metadata: + NotFound: Метаданните не са намерени + NoData: Списъкът с метаданни е празен + Invalid: Метаданните са невалидни + KeyNotExisting: Един или повече ключове не съществуват + Action: + Invalid: Действието е невалидно + NotFound: Действието не е намерено + NotActive: Действието не е активно + NotInactive: Действието не е неактивно + MaxAllowed: Не са разрешени допълнителни активни действия + Flow: + FlowTypeMissing: Липсва FlowType + Empty: Потокът вече е празен + WrongTriggerType: TriggerType е невалиден + NoChanges: Без промени + ActionIDsNotExist: ActionIDs не съществуват + Query: + CloseRows: SQL изразът не можа да бъде завършен + SQLStatement: SQL изразът не може да бъде създаден + InvalidRequest: Заявката е невалидна + Quota: + AlreadyExists: Вече съществува квота за тази единица + NotFound: Не е намерена квота за тази единица + Invalid: + CallURL: URL адресът за обаждане с квота е невалиден + Percent: Процентът на квотата е по-нисък от 1 + Unimplemented: За тази единица не се прилагат квоти + Amount: Сумата на квотата е по-ниска от 1 + ResetInterval: Интервалът за нулиране на квотата е по-кратък от минута + Noop: Неограничена квота без известия няма ефект + Access: + Exhausted: Квотата за удостоверени заявки е изчерпана + Execution: + Exhausted: Квотата за секунди за изпълнение е изчерпана + LogStore: + Access: + StorageFailed: >- + Съхраняването на регистрационния файл за достъп в базата данни не бе + успешно + ScanFailed: Неуспешно запитване за използване за удостоверени заявки + Execution: + StorageFailed: >- + Неуспешно съхраняване на регистрационния файл за изпълнение на действие + в базата данни + ScanFailed: Неуспешно запитване за използване за секунди изпълнение на действие + Session: + NotExisting: Сесията не съществува + Terminated: Сесията вече е прекратена + Token: + Invalid: Токенът на сесията е невалиден + Passkey: + NoChallenge: Сесия без предизвикателство за парола + Intent: + IDPMissing: IDP липсва в заявката + SuccessURLMissing: В заявката липсва URL адрес за успех + FailureURLMissing: В заявката липсва URL адрес за грешка + StateMissing: В заявката липсва параметър състояние + NotStarted: Намерението не е стартирано или вече е прекратено + NotSucceeded: Намерението не е успешно + TokenCreationFailed: Неуспешно създаване на токен + InvalidToken: Знакът за намерение е невалиден + OtherUser: Намерение, предназначено за друг потребител + +AggregateTypes: + action: Действие + instance: Инстанция + key_pair: Двойка ключове + org: Организация + project: Проект + user: Потребител + usergrant: Предоставяне на потребител + quota: Квота +EventTypes: + user: + added: Добавен потребител + selfregistered: Потребителят се регистрира сам + initialization: + code: + added: Генериран код за инициализиране + sent: Кодът за инициализиране е изпратен + check: + succeeded: Проверката за инициализация е успешна + failed: Проверката на инициализацията е неуспешна + token: + added: Токенът за достъп е създаден + removed: Токенът за достъп е премахнат + username: + reserved: Потребителското име е запазено + released: Потребителското име е освободено + changed: Потребителското име е променено + email: + reserved: Имейл адресът е запазен + released: Имейл адресът е освободен + changed: Имейл адресът е променен + verified: Имейл адресът е потвърден + verification: + failed: Проверката на имейл адреса не бе успешна + code: + added: Генериран код за потвърждение на имейл адрес + sent: Кодът за потвърждение на имейл адреса е изпратен + machine: + added: Добавен е технически потребител + changed: Техническият потребител е променен + key: + added: Ключът е добавен + removed: Ключът е премахнат + secret: + set: Секретен комплект + removed: Тайната е премахната + check: + succeeded: Тайната проверка е успешна + failed: Тайната проверка е неуспешна + human: + added: Добавено лице + selfregistered: Човек се регистрира сам + avatar: + added: Аватарът е добавен + removed: Аватарът премахнат + initialization: + code: + added: Генериран код за инициализиране + sent: Кодът за инициализиране е изпратен + check: + succeeded: Проверката за инициализация е успешна + failed: Проверката на инициализацията е неуспешна + username: + reserved: Потребителското име е запазено + released: Потребителското име е освободено + email: + changed: Имейл адресът е променен + verified: Имейл адресът е потвърден + verification: + failed: Проверката на имейл адреса не бе успешна + code: + added: Генериран код за потвърждение на имейл адрес + sent: Кодът за потвърждение на имейл адреса е изпратен + password: + changed: паролата е сменена + code: + added: Кодът на паролата е генериран + sent: Кодът за парола е изпратен + check: + succeeded: Проверката на паролата е успешна + failed: Проверката на паролата е неуспешна + externallogin: + check: + succeeded: Външното влизане бе успешно + externalidp: + added: Добавен външен IDP + removed: Външният IDP е премахнат + cascade: + removed: Външната IDP каскада е премахната + phone: + changed: Телефонният номер е променен + verified: Телефонният номер е потвърден + verification: + failed: Неуспешна проверка на телефонния номер + code: + added: Генериран код на телефонен номер + sent: Кодът на телефонния номер е изпратен + removed: Телефонният номер е премахнат + profile: + changed: Променен потребителски профил + address: + changed: Потребителският адрес е променен + mfa: + otp: + added: Добавен е многофакторен OTP + verified: Многофакторно OTP потвърдено + removed: Многофакторният OTP премахнат + check: + succeeded: Многофакторната OTP проверка е успешна + failed: Многофакторната OTP проверка е неуспешна + u2f: + token: + added: Добавен е многофакторен U2F токен + verified: Multifactor U2F Token е проверен + removed: Multifactor U2F Token премахнат + begin: + login: Многофакторната U2F проверка започна + check: + succeeded: Многофакторната U2F проверка е успешна + failed: Многофакторната U2F проверка е неуспешна + signcount: + changed: Контролната сума на Multifactor U2F Token е променена + init: + skipped: Многофакторната инициализация е пропусната + passwordless: + token: + added: Добавен е токен за влизане без парола + verified: Токенът за влизане без парола е потвърден + removed: Токенът за влизане без парола е премахнат + begin: + login: Започна проверка за влизане без парола + check: + succeeded: Проверката за влизане без парола е успешна + failed: Проверката за влизане без парола е неуспешна + signcount: + changed: Контролната сума на токена за влизане без парола е променена + initialization: + code: + added: Добавен код за инициализация без парола + sent: Кодът за инициализация без парола е изпратен + requested: Изисква се код за инициализация без парола + check: + succeeded: Кодът за инициализация без парола е проверен успешно + failed: Проверката на кода за инициализация без парола е неуспешна + signed: + out: Потребителят е излязъл + refresh: + token: + added: Създаден токен за опресняване + renewed: Токенът за обновяване е подновен + removed: Токенът за обновяване е премахнат + locked: Потребителят е заключен + unlocked: Потребителят е отключен + deactivated: Потребителят е деактивиран + reactivated: Потребителят е повторно активиран + removed: Потребителят е премахнат + password: + changed: паролата е сменена + code: + added: Кодът на паролата е генериран + sent: Кодът за парола е изпратен + check: + succeeded: Проверката на паролата е успешна + failed: Проверката на паролата е неуспешна + phone: + changed: Телефонният номер е променен + verified: Телефонният номер е потвърден + verification: + failed: Неуспешна проверка на телефонния номер + code: + added: Генериран код на телефонен номер + sent: Кодът на телефонния номер е изпратен + removed: Телефонният номер е премахнат + profile: + changed: Променен потребителски профил + address: + changed: Потребителският адрес е променен + mfa: + otp: + added: Добавен е многофакторен OTP + verified: Многофакторно OTP потвърдено + removed: Многофакторният OTP премахнат + check: + succeeded: Многофакторната OTP проверка е успешна + failed: Многофакторната OTP проверка е неуспешна + init: + skipped: Многофакторната OTP инициализация е пропусната + init: + skipped: Многофакторната инициализация е пропусната + signed: + out: Потребителят е излязъл + grant: + added: Упълномощаването е добавено + changed: Разрешението е променено + removed: Упълномощаването е премахнато + deactivated: Упълномощаването е деактивирано + reactivated: Упълномощаването е повторно активирано + reserved: Разрешението е запазено + released: Разрешението е пуснато + cascade: + removed: Упълномощаването е премахнато + changed: Разрешението е променено + metadata: + set: Набор от потребителски метаданни + removed: Потребителските метаданни са премахнати + removed.all: Всички потребителски метаданни са премахнати + domain: + claimed: Заявен домейн + claimed.sent: Известието за заявен домейн е изпратено + pat: + added: Добавен личен токен за достъп + removed: Личният маркер за достъп е премахнат + org: + added: Добавена е организация + changed: Организацията се промени + deactivated: Организацията е деактивирана + reactivated: Организацията е активирана отново + removed: Организацията е премахната + domain: + added: Домейнът е добавен + verification: + added: Добавена е проверка на домейна + failed: Неуспешна проверка на домейна + verified: Домейнът е потвърден + removed: Домейнът премахнат + primary: + set: Основен набор от домейни + reserved: Домейнът е запазен + released: Домейнът е освободен + name: + reserved: Името на организацията е запазено + released: Името на организацията е публикувано + member: + added: Добавен е член на организацията + changed: Членът на организацията е променен + removed: Премахнат член на организацията + cascade: + removed: Каскадата на членовете на организацията е премахната + iam: + policy: + added: Добавена е системна политика + changed: Системната политика е променена + removed: Системната политика е премахната + idp: + config: + added: IDP конфигурация е добавена + changed: IDP конфигурацията е променена + removed: IDP конфигурацията е премахната + deactivated: IDP конфигурацията е деактивирана + reactivated: IDP конфигурацията е активирана отново + oidc: + config: + added: Добавена е OIDC IDP конфигурация + changed: IDP конфигурацията на OIDC е променена + saml: + config: + added: Добавена е SAML IDP конфигурация + changed: SAML IDP конфигурацията е променена + jwt: + config: + added: Добавена е конфигурация на JWT IDP + changed: Конфигурацията на JWT IDP е променена + customtext: + set: Персонализиран текстов набор + removed: Персонализираният текст е премахнат + template: + removed: Персонализираният текстов шаблон е премахнат + policy: + login: + added: Добавена е политика за влизане + changed: Правилата за влизане са променени + removed: Правилата за влизане са премахнати + idpprovider: + added: Доставчикът на самоличност е добавен към правилата за влизане + removed: Доставчикът на самоличност е премахнат от правилата за влизане + cascade: + removed: >- + Каскадата на доставчика на самоличност е премахната от правилата + за влизане + secondfactor: + added: Вторият фактор е добавен към правилата за влизане + removed: Вторият фактор е премахнат от правилата за влизане + multifactor: + added: 'Много фактор, добавен към правилата за влизане' + removed: Мултифакторът е премахнат от правилата за влизане + password: + complexity: + added: Добавена е политика за сложността на паролата + changed: Правилата за сложността на паролите са променени + removed: Правилата за сложността на паролите са премахнати + age: + added: Добавена е политика за възраст на паролата + changed: Правилата за възрастта на паролата са променени + removed: Правилото за възрастта на паролата е премахнато + lockout: + added: Добавена е политика за блокиране на парола + changed: Правилата за блокиране на пароли са променени + removed: Правилата за блокиране на пароли са премахнати + label: + added: Добавена е политика за етикети + changed: Правилата за етикети са променени + activated: Правилата за етикети са активирани + removed: Правилата за етикети са премахнати + logo: + added: Логото е добавено към правилата за етикети + removed: Логото е премахнато от правилата за етикети + dark: + added: Лого (тъмен режим) е добавено към правилата за етикети + removed: Логото (тъмен режим) е премахнато от правилата за етикети + icon: + added: Иконата е добавена към правилата за етикети + removed: Иконата е премахната от правилата за етикети + dark: + added: Икона (тъмен режим) е добавена към правилата за етикети + removed: Икона (тъмен режим) премахната от правилата за етикети + font: + added: Шрифтът е добавен към правилата за етикети + removed: Шрифтът е премахнат от правилата за етикети + assets: + removed: Активите са премахнати от правилата за етикети + privacy: + added: Добавени са политика за поверителност и TOS + changed: Политиката за поверителност и TOS са променени + removed: Правилата за поверителност и TOS премахнати + domain: + added: Добавена е политика за домейн + changed: Правилата на домейна са променени + removed: Правилата за домейни са премахнати + lockout: + added: Добавена е политика за блокиране + changed: Политиката за блокиране е променена + removed: Политиката за блокиране е премахната + notification: + added: Добавена е политика за уведомяване + changed: Правилата за уведомяване са променени + removed: Правилата за уведомяване са премахнати + flow: + trigger_actions: + set: Комплект действия + cascade: + removed: Каскадата от действия е премахната + removed: Премахнати действия + cleared: Потокът е изчистен + mail: + template: + added: Добавен шаблон за имейл + changed: Шаблонът за имейл е променен + removed: Шаблонът за имейл е премахнат + text: + added: Добавен е имейл текст + changed: Текстът на имейла е променен + removed: Текстът на имейла е премахнат + metadata: + removed: Метаданните са премахнати + removed.all: Всички метаданни са премахнати + set: Набор метаданни + project: + added: Проектът е добавен + changed: Проектът е променен + deactivated: Проектът е деактивиран + reactivated: Проектът е активиран отново + removed: Проектът е премахнат + member: + added: Добавен член на проекта + changed: Членът на проекта е променен + removed: Членът на проекта е премахнат + cascade: + removed: Каскадата от членове на проекта е премахната + role: + added: Добавена е роля в проекта + changed: Ролята на проекта е променена + removed: Ролята в проекта е премахната + grant: + added: Добавен е достъп за управление + changed: Достъпът за управление е променен + removed: Достъпът за управление е премахнат + deactivated: Достъпът за управление е деактивиран + reactivated: Достъпът за управление е активиран отново + cascade: + changed: Достъпът за управление е променен + member: + added: Добавен е член с достъп за управление + changed: Членът с достъп за управление е променен + removed: Членът с достъп за управление е премахнат + cascade: + removed: Каскадата за достъп до управление е премахната + application: + added: Приложението е добавено + changed: Приложението е променено + removed: Приложението е премахнато + deactivated: Приложението е деактивирано + reactivated: Приложението е активирано повторно + oidc: + secret: + check: + succeeded: Проверката на OIDC Client Secret е успешна + failed: Проверката на OIDC Client Secret е неуспешна + key: + added: Добавен ключ за приложение + removed: Ключът на приложението е премахнат + config: + saml: + added: Добавена е SAML конфигурация + changed: SAML конфигурацията е променена + oidc: + added: Добавена е OIDC конфигурация + changed: Конфигурацията на OIDC е променена + secret: + changed: Тайната на OIDC е променена + api: + added: Добавена е конфигурация на API + changed: Променена конфигурация на API + secret: + changed: Тайната на API е променена + policy: + password: + complexity: + added: Добавена е политика за сложността на паролата + changed: Правилата за сложността на паролите са променени + age: + added: Добавена е политика за възраст на паролата + changed: Правилата за възрастта на паролата са променени + lockout: + added: Добавена е политика за блокиране на парола + changed: Правилата за блокиране на пароли са променени + iam: + setup: + started: Настройката на ZITADEL започна + done: Настройката на ZITADEL е готова + global: + org: + set: Глобален организационен набор + project: + iam: + set: Комплект проект ZITADEL + member: + added: Добавен е член на ZITADEL + changed: Членът на ZITADEL е променен + removed: Член на ZITADEL премахнат + cascade: + removed: Каскадата на членове на ZITADEL е премахната + idp: + config: + added: IDP конфигурация е добавена + changed: IDP конфигурацията е променена + removed: IDP конфигурацията е премахната + deactivated: IDP конфигурацията е деактивирана + reactivated: IDP конфигурацията е активирана отново + oidc: + config: + added: Добавена е OIDC IDP конфигурация + changed: IDP конфигурацията на OIDC е променена + saml: + config: + added: Добавена е SAML IDP конфигурация + changed: SAML IDP конфигурацията е променена + jwt: + config: + added: Добавена е конфигурация на JWT към доставчик на идентичност + changed: Конфигурацията на JWT от доставчика на идентичност е премахната + customtext: + set: Текстът беше зададен + removed: Текстът беше премахнат + policy: + login: + added: Добавена е политиката за влизане по подразбиране + changed: Правилата за влизане по подразбиране са променени + idpprovider: + added: >- + Доставчикът на самоличност е добавен към правилата за влизане по + подразбиране + removed: >- + Доставчикът на самоличност е премахнат от правилата за влизане по + подразбиране + label: + added: Добавена е политика за етикети + changed: Правилата за етикети са променени + activated: Правилата за етикети са активирани + logo: + added: Логото е добавено към правилата за етикети + removed: Логото е премахнато от правилата за етикети + dark: + added: Лого (тъмен режим) е добавено към правилата за етикети + removed: Логото (тъмен режим) е премахнато от правилата за етикети + icon: + added: Иконата е добавена към правилата за етикети + removed: Иконата е премахната от правилата за етикети + dark: + added: Икона (тъмен режим) е добавена към правилата за етикети + removed: Икона (тъмен режим) премахната от правилата за етикети + font: + added: Шрифтът е добавен към правилата за етикети + removed: Шрифтът е премахнат от правилата за етикети + assets: + removed: Активите са премахнати от правилата за етикети + default: + language: + set: Зададен език по подразбиране + oidc: + settings: + added: Добавена е OIDC конфигурация + changed: Конфигурацията на OIDC е променена + removed: OIDC конфигурацията е премахната + secret: + generator: + added: Добавен е таен генератор + changed: Променен секретен генератор + removed: Секретният генератор е премахнат + smtp: + config: + added: Добавена е SMTP конфигурация + changed: SMTP конфигурацията е променена + password: + changed: Тайната на конфигурацията на SMTP е променена + sms: + config: + twilio: + added: Добавен е доставчик на SMS Twilio + changed: Доставчикът на Twilio SMS е променен + token: + changed: Токенът на доставчика на SMS на Twilio е променен + removed: Доставчикът на Twilio SMS е премахнат + activated: Twilio SMS доставчик е активиран + deactivated: Доставчикът на Twilio SMS е деактивиран + key_pair: + added: Добавена двойка ключове + certificate: + added: Сертификатът е добавен + action: + added: Добавено действие + changed: Действието е променено + deactivated: Действието е деактивирано + reactivated: Действието е активирано повторно + removed: Действието е премахнато + instance: + added: Добавен екземпляр + changed: Екземплярът е променен + customtext: + removed: Персонализираният текст е премахнат + set: Персонализиран текстов набор + template: + removed: Шаблонът за персонализиран текст е премахнат + default: + language: + set: Зададен език по подразбиране + org: + set: Организация по подразбиране + domain: + added: Домейнът е добавен + primary: + set: Основен набор от домейни + removed: Домейнът премахнат + iam: + console: + set: Комплект конзолни приложения ZITADEL + project: + set: Комплект проект ZITADEL + mail: + template: + added: Добавен шаблон за имейл + changed: Шаблонът за имейл е променен + text: + added: Добавен е имейл текст + changed: Текстът на имейла е променен + member: + added: Добавен е член на екземпляра + changed: Членът на екземпляра е променен + removed: Членът на екземпляра е премахнат + cascade: + removed: Каскадата от членове на екземпляра е премахната + notification: + provider: + debug: + fileadded: Добавен е доставчик на известия за отстраняване на грешки + filechanged: >- + Доставчикът на известия за отстраняване на грешки на файлове е + променен + fileremoved: >- + Доставчикът на известия за отстраняване на грешки на файлове е + премахнат + logadded: Добавен е доставчик на известия за отстраняване на грешки в журнала + logchanged: >- + Доставчикът на известия за отстраняване на грешки в журнала е + променен + logremoved: >- + Доставчикът на известия за отстраняване на грешки в журнала е + премахнат + oidc: + settings: + added: Добавени са настройки на OIDC + changed: Настройките на OIDC са променени + policy: + domain: + added: Добавена е политика за домейн + changed: Правилата на домейна са променени + label: + activated: Правилата за етикети са активирани + added: Добавена е политика за етикети + assets: + removed: Правилата за актив от етикета са премахнати + changed: Правилата за етикети са променени + font: + added: Шрифтът е добавен към правилата за етикети + removed: Шрифтът е премахнат от правилата за етикети + icon: + added: Иконата е добавена към правилата за етикети + removed: Иконата е премахната от правилата за етикети + dark: + added: Иконата е добавена към правилата за тъмни етикети + removed: Иконата е премахната от правилата за тъмни етикети + logo: + added: Логото е добавено към правилата за етикети + removed: Логото е премахнато от правилата за етикети + dark: + added: Логото е добавено към правилата за тъмни етикети + removed: Логото е премахнато от правилата за тъмни етикети + lockout: + added: Добавена е политика за блокиране + changed: Политиката за блокиране е променена + login: + added: Добавена е политика за влизане + changed: Правилата за влизане са променени + idpprovider: + added: Доставчикът на самоличност е добавен към правилата за влизане + cascade: + removed: >- + Каскадата на доставчика на самоличност е премахната от правилата + за влизане + removed: Доставчикът на самоличност е премахнат от правилата за влизане + multifactor: + added: Мултифакторът е добавен към правилата за влизане + removed: Multifactor е премахнат от политиката за влизане + secondfactor: + added: Вторият фактор е добавен към правилата за влизане + removed: Вторият фактор е премахнат от правилата за влизане + password: + age: + added: Добавена е политика за възраст на паролата + changed: Правилата за възрастта на паролата са променени + complexity: + added: Добавена е политика за сложността на паролата + changed: Правилата за сложността на паролите са премахнати + privacy: + added: Добавена е политика за поверителност + changed: Политиката за поверителност е променена + security: + set: Зададена политика за сигурност + removed: Екземплярът е премахнат + secret: + generator: + added: Добавен е таен генератор + changed: Променен секретен генератор + removed: Секретният генератор е премахнат + sms: + configtwilio: + activated: Конфигурацията на Twilio SMS е активирана + added: Добавена е конфигурация на Twilio SMS + changed: Конфигурацията на Twilio SMS е променена + deactivated: Конфигурацията на Twilio SMS е деактивирана + removed: SMS конфигурацията на Twilio е премахната + token: + changed: Конфигурацията на Token на Twilio SMS е променена + smtp: + config: + added: Добавена е SMTP конфигурация + changed: SMTP конфигурацията е променена + password: + changed: Паролата на SMTP конфигурацията е променена + removed: Премахната SMTP конфигурация +Application: + OIDC: + UnsupportedVersion: Вашата OIDC версия не се поддържа + V1: + NotCompliant: >- + Вашата конфигурация не е съвместима и се различава от стандарта OIDC + 1.0. + NoRedirectUris: Поне един uri адрес за пренасочване трябва да бъде регистриран. + NotAllCombinationsAreAllowed: >- + Конфигурацията е съвместима, но не всички възможни комбинации са + разрешени. + Code: + RedirectUris: + HttpOnlyForWeb: >- + Предоставяне на код за тип разрешено само http пренасочване URIS за + apptype web. + CustomOnlyForNative: >- + Кодът за тип предоставяне позволява само потребителски uris адрес за + пренасочване за родния тип на приложението (напр. име на + приложение:// ) + Implicit: + RedirectUris: + CustomNotAllowed: >- + Видът на предоставяне имплицитно не позволява потребителски uris + адрес за пренасочване + HttpNotAllowed: >- + Видът на предоставяне имплицитно не позволява URL адрес за + пренасочване на http + HttpLocalhostOnlyForNative: >- + URI за пренасочване на Http://localhost е разрешен само за собствени + приложения. + Native: + AuthMethodType: + NotNone: Родните приложения трябва да имат authmethodtype none. + RedirectUris: + MustBeHttpLocalhost: >- + URI адресите за пренасочване трябва да започват с вашия собствен + протокол, http://127.0.0.1, http://[::1] или http://localhost. + UserAgent: + AuthMethodType: + NotNone: >- + Приложението на потребителски агент трябва да има authmethodtype + none. + GrantType: + Refresh: + NoAuthCode: >- + Токенът за опресняване е разрешен само в комбинация с код за + оторизация. +Action: + Flow: + Type: + Unspecified: Неуточнено + ExternalAuthentication: Външно удостоверяване + CustomiseToken: Токен за допълнение + InternalAuthentication: Вътрешно удостоверяване + TriggerType: + Unspecified: Неуточнено + PostAuthentication: Публикуване на автентификация + PreCreation: Предварително създаване + PostCreation: Създаване на публикации + PreUserinfoCreation: Предварително създаване на потребителска информация + PreAccessTokenCreation: Създаване на маркер за предварителен достъп diff --git a/internal/static/i18n/de.yaml b/internal/static/i18n/de.yaml index 6d830b2de..846e09dff 100644 --- a/internal/static/i18n/de.yaml +++ b/internal/static/i18n/de.yaml @@ -487,6 +487,7 @@ Errors: NotSucceeded: Intent war nicht erfolgreich TokenCreationFailed: Tokenerstellung schlug fehl InvalidToken: Intent Token ist ungültig + OtherUser: Intent ist für anderen Benutzer gedacht AggregateTypes: action: Action diff --git a/internal/static/i18n/en.yaml b/internal/static/i18n/en.yaml index 88763384e..5986651ea 100644 --- a/internal/static/i18n/en.yaml +++ b/internal/static/i18n/en.yaml @@ -487,6 +487,7 @@ Errors: NotSucceeded: Intent has not succeeded TokenCreationFailed: Token creation failed InvalidToken: Intent Token is invalid + OtherUser: Intent meant for another user AggregateTypes: action: Action diff --git a/internal/static/i18n/es.yaml b/internal/static/i18n/es.yaml index dbfa308c8..1adb10763 100644 --- a/internal/static/i18n/es.yaml +++ b/internal/static/i18n/es.yaml @@ -487,6 +487,7 @@ Errors: NotSucceeded: Intento fallido TokenCreationFailed: Fallo en la creación del token InvalidToken: El token de la intención no es válido + OtherUser: Destinado a otro usuario AggregateTypes: action: Acción diff --git a/internal/static/i18n/fr.yaml b/internal/static/i18n/fr.yaml index 9d4c03ed6..5789a815c 100644 --- a/internal/static/i18n/fr.yaml +++ b/internal/static/i18n/fr.yaml @@ -487,6 +487,7 @@ Errors: NotSucceeded: l'intention n'a pas abouti TokenCreationFailed: La création du token a échoué InvalidToken: Le jeton d'intention n'est pas valide + OtherUser: Intention destinée à un autre utilisateur AggregateTypes: action: Action diff --git a/internal/static/i18n/it.yaml b/internal/static/i18n/it.yaml index 113e99c30..4e51b0fc3 100644 --- a/internal/static/i18n/it.yaml +++ b/internal/static/i18n/it.yaml @@ -487,6 +487,7 @@ Errors: NotSucceeded: l'intento non è andato a buon fine TokenCreationFailed: creazione del token fallita InvalidToken: Il token dell'intento non è valido + OtherUser: Intento destinato a un altro utente AggregateTypes: action: Azione diff --git a/internal/static/i18n/ja.yaml b/internal/static/i18n/ja.yaml index fd2fd5abe..ed6d070d1 100644 --- a/internal/static/i18n/ja.yaml +++ b/internal/static/i18n/ja.yaml @@ -476,6 +476,7 @@ Errors: NotSucceeded: インテントが成功しなかった TokenCreationFailed: トークンの作成に失敗しました InvalidToken: インテントのトークンが無効である + OtherUser: 他のユーザーを意図している AggregateTypes: action: アクション diff --git a/internal/static/i18n/pl.yaml b/internal/static/i18n/pl.yaml index 0c7e56ccd..9e907dcbe 100644 --- a/internal/static/i18n/pl.yaml +++ b/internal/static/i18n/pl.yaml @@ -487,6 +487,7 @@ Errors: NotSucceeded: intencja nie powiodła się TokenCreationFailed: Tworzenie tokena nie powiodło się InvalidToken: Token intencji jest nieprawidłowy + OtherUser: Intencja przeznaczona dla innego użytkownika AggregateTypes: action: Działanie diff --git a/internal/static/i18n/zh.yaml b/internal/static/i18n/zh.yaml index 3a1508e05..2a9f2400f 100644 --- a/internal/static/i18n/zh.yaml +++ b/internal/static/i18n/zh.yaml @@ -487,6 +487,7 @@ Errors: NotSucceeded: 意图不成功 TokenCreationFailed: 令牌创建失败 InvalidToken: 意图令牌是无效的 + OtherUser: 意图是为另一个用户准备的 AggregateTypes: action: 动作 diff --git a/internal/webauthn/converter.go b/internal/webauthn/converter.go index 9b49ec016..36799ee3d 100644 --- a/internal/webauthn/converter.go +++ b/internal/webauthn/converter.go @@ -7,10 +7,10 @@ import ( "github.com/zitadel/zitadel/internal/domain" ) -func WebAuthNsToCredentials(webAuthNs []*domain.WebAuthNToken) []webauthn.Credential { +func WebAuthNsToCredentials(webAuthNs []*domain.WebAuthNToken, rpID string) []webauthn.Credential { creds := make([]webauthn.Credential, 0) for _, webAuthN := range webAuthNs { - if webAuthN.State == domain.MFAStateReady { + if webAuthN.State == domain.MFAStateReady && webAuthN.RPID == rpID { creds = append(creds, webauthn.Credential{ ID: webAuthN.KeyID, PublicKey: webAuthN.PublicKey, diff --git a/internal/webauthn/webauthn.go b/internal/webauthn/webauthn.go index 5d2517bc4..bced4f220 100644 --- a/internal/webauthn/webauthn.go +++ b/internal/webauthn/webauthn.go @@ -52,12 +52,12 @@ func (u *webUser) WebAuthnCredentials() []webauthn.Credential { return u.credentials } -func (w *Config) BeginRegistration(ctx context.Context, user *domain.Human, accountName string, authType domain.AuthenticatorAttachment, userVerification domain.UserVerificationRequirement, isLoginUI bool, webAuthNs ...*domain.WebAuthNToken) (*domain.WebAuthNToken, error) { - webAuthNServer, err := w.serverFromContext(ctx) +func (w *Config) BeginRegistration(ctx context.Context, user *domain.Human, accountName string, authType domain.AuthenticatorAttachment, userVerification domain.UserVerificationRequirement, rpID string, webAuthNs ...*domain.WebAuthNToken) (*domain.WebAuthNToken, error) { + webAuthNServer, err := w.serverFromContext(ctx, rpID, "") if err != nil { return nil, err } - creds := WebAuthNsToCredentials(webAuthNs) + creds := WebAuthNsToCredentials(webAuthNs, rpID) existing := make([]protocol.CredentialDescriptor, len(creds)) for i, cred := range creds { existing[i] = protocol.CredentialDescriptor{ @@ -90,6 +90,7 @@ func (w *Config) BeginRegistration(ctx context.Context, user *domain.Human, acco CredentialCreationData: cred, AllowedCredentialIDs: sessionData.AllowedCredentialIDs, UserVerification: UserVerificationToDomain(sessionData.UserVerification), + RPID: webAuthNServer.Config.RPID, }, nil } @@ -104,7 +105,7 @@ func (w *Config) FinishRegistration(ctx context.Context, user *domain.Human, web return nil, caos_errs.ThrowInternal(err, "WEBAU-sEr8c", "Errors.User.WebAuthN.ErrorOnParseCredential") } sessionData := WebAuthNToSessionData(webAuthN) - webAuthNServer, err := w.serverFromContext(ctx) + webAuthNServer, err := w.serverFromContext(ctx, webAuthN.RPID, credentialData.Response.CollectedClientData.Origin) if err != nil { return nil, err } @@ -124,17 +125,18 @@ func (w *Config) FinishRegistration(ctx context.Context, user *domain.Human, web webAuthN.AAGUID = credential.Authenticator.AAGUID webAuthN.SignCount = credential.Authenticator.SignCount webAuthN.WebAuthNTokenName = tokenName + webAuthN.RPID = webAuthNServer.Config.RPID return webAuthN, nil } -func (w *Config) BeginLogin(ctx context.Context, user *domain.Human, userVerification domain.UserVerificationRequirement, webAuthNs ...*domain.WebAuthNToken) (*domain.WebAuthNLogin, error) { - webAuthNServer, err := w.serverFromContext(ctx) +func (w *Config) BeginLogin(ctx context.Context, user *domain.Human, userVerification domain.UserVerificationRequirement, rpID string, webAuthNs ...*domain.WebAuthNToken) (*domain.WebAuthNLogin, error) { + webAuthNServer, err := w.serverFromContext(ctx, rpID, "") if err != nil { return nil, err } assertion, sessionData, err := webAuthNServer.BeginLogin(&webUser{ Human: user, - credentials: WebAuthNsToCredentials(webAuthNs), + credentials: WebAuthNsToCredentials(webAuthNs, rpID), }, webauthn.WithUserVerification(UserVerificationFromDomain(userVerification))) if err != nil { return nil, caos_errs.ThrowInternal(err, "WEBAU-4G8sw", "Errors.User.WebAuthN.BeginLoginFailed") @@ -148,6 +150,7 @@ func (w *Config) BeginLogin(ctx context.Context, user *domain.Human, userVerific CredentialAssertionData: cred, AllowedCredentialIDs: sessionData.AllowedCredentialIDs, UserVerification: userVerification, + RPID: webAuthNServer.Config.RPID, }, nil } @@ -158,9 +161,9 @@ func (w *Config) FinishLogin(ctx context.Context, user *domain.Human, webAuthN * } webUser := &webUser{ Human: user, - credentials: WebAuthNsToCredentials(webAuthNs), + credentials: WebAuthNsToCredentials(webAuthNs, webAuthN.RPID), } - webAuthNServer, err := w.serverFromContext(ctx) + webAuthNServer, err := w.serverFromContext(ctx, webAuthN.RPID, assertionData.Response.CollectedClientData.Origin) if err != nil { return nil, 0, err } @@ -175,15 +178,31 @@ func (w *Config) FinishLogin(ctx context.Context, user *domain.Human, webAuthN * return credential.ID, credential.Authenticator.SignCount, nil } -func (w *Config) serverFromContext(ctx context.Context) (*webauthn.WebAuthn, error) { - instance := authz.GetInstance(ctx) - webAuthn, err := webauthn.New(&webauthn.Config{ - RPDisplayName: w.DisplayName, - RPID: instance.RequestedDomain(), - RPOrigins: []string{http.BuildOrigin(instance.RequestedHost(), w.ExternalSecure)}, - }) +func (w *Config) serverFromContext(ctx context.Context, id, origin string) (*webauthn.WebAuthn, error) { + config := w.config(id, origin) + if id == "" { + config = w.configFromContext(ctx) + } + webAuthn, err := webauthn.New(config) if err != nil { return nil, caos_errs.ThrowInternal(err, "WEBAU-UX9ta", "Errors.User.WebAuthN.ServerConfig") } return webAuthn, nil } + +func (w *Config) configFromContext(ctx context.Context) *webauthn.Config { + instance := authz.GetInstance(ctx) + return &webauthn.Config{ + RPDisplayName: w.DisplayName, + RPID: instance.RequestedDomain(), + RPOrigins: []string{http.BuildOrigin(instance.RequestedHost(), w.ExternalSecure)}, + } +} + +func (w *Config) config(id, origin string) *webauthn.Config { + return &webauthn.Config{ + RPDisplayName: w.DisplayName, + RPID: id, + RPOrigins: []string{origin}, + } +} diff --git a/internal/webauthn/webauthn_test.go b/internal/webauthn/webauthn_test.go index df05d34e9..7d8052048 100644 --- a/internal/webauthn/webauthn_test.go +++ b/internal/webauthn/webauthn_test.go @@ -14,7 +14,9 @@ import ( func TestConfig_serverFromContext(t *testing.T) { type args struct { - ctx context.Context + ctx context.Context + id string + origin string } tests := []struct { name string @@ -24,12 +26,12 @@ func TestConfig_serverFromContext(t *testing.T) { }{ { name: "webauthn error", - args: args{context.Background()}, + 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")}, + name: "success from ctx", + args: args{authz.WithRequestedDomain(context.Background(), "example.com"), "", ""}, want: &webauthn.WebAuthn{ Config: &webauthn.Config{ RPDisplayName: "DisplayName", @@ -38,6 +40,17 @@ func TestConfig_serverFromContext(t *testing.T) { }, }, }, + { + name: "success from id", + args: args{authz.WithRequestedDomain(context.Background(), "example.com"), "external.com", "https://external.com"}, + want: &webauthn.WebAuthn{ + Config: &webauthn.Config{ + RPDisplayName: "DisplayName", + RPID: "external.com", + RPOrigins: []string{"https://external.com"}, + }, + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -45,7 +58,7 @@ func TestConfig_serverFromContext(t *testing.T) { DisplayName: "DisplayName", ExternalSecure: true, } - got, err := w.serverFromContext(tt.args.ctx) + got, err := w.serverFromContext(tt.args.ctx, tt.args.id, tt.args.origin) require.ErrorIs(t, err, tt.wantErr) if tt.want != nil { require.NotNil(t, got) diff --git a/proto/zitadel/session/v2alpha/session.proto b/proto/zitadel/session/v2alpha/session.proto index 79f203086..b3e11a443 100644 --- a/proto/zitadel/session/v2alpha/session.proto +++ b/proto/zitadel/session/v2alpha/session.proto @@ -39,12 +39,18 @@ message Session { description: "\"custom key value list\""; } ]; + string domain = 7 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "\"domain on which the session was created\""; + } + ]; } message Factors { UserFactor user = 1; PasswordFactor password = 2; PasskeyFactor passkey = 3; + IntentFactor intent = 4; } message UserFactor { @@ -78,6 +84,14 @@ message PasswordFactor { ]; } +message IntentFactor { + google.protobuf.Timestamp verified_at = 1 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "\"time when an intent was last checked\""; + } + ]; +} + message PasskeyFactor { google.protobuf.Timestamp verified_at = 1 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { diff --git a/proto/zitadel/session/v2alpha/session_service.proto b/proto/zitadel/session/v2alpha/session_service.proto index 0ee4b05d3..270317626 100644 --- a/proto/zitadel/session/v2alpha/session_service.proto +++ b/proto/zitadel/session/v2alpha/session_service.proto @@ -245,6 +245,11 @@ message CreateSessionRequest{ } ]; repeated ChallengeKind challenges = 3; + string domain = 4 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "\"Domain on which the session was created. Will be used for Passkey and U2F challenges.\""; + } + ]; } message CreateSessionResponse{ @@ -341,6 +346,11 @@ message Checks { description: "\"Checks the public key credential issued by the passkey client. Requires that the user is already checked and a passkey challenge to be requested, in any previous request.\""; } ]; + optional CheckIntent intent = 4 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "\"Checks the intent. Requires that the userlink is already checked and a successful intent.\""; + } + ]; } message CheckUser { @@ -386,3 +396,24 @@ message CheckPasskey { } ]; } + +message CheckIntent { + 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=\""; + } + ]; +} diff --git a/proto/zitadel/user/v2alpha/idp.proto b/proto/zitadel/user/v2alpha/idp.proto index ed8f389c3..5996df57a 100644 --- a/proto/zitadel/user/v2alpha/idp.proto +++ b/proto/zitadel/user/v2alpha/idp.proto @@ -5,14 +5,41 @@ package zitadel.user.v2alpha; option go_package = "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha;user"; import "google/api/field_behavior.proto"; +import "google/protobuf/struct.proto"; import "protoc-gen-openapiv2/options/annotations.proto"; import "validate/validate.proto"; message IDPInformation{ oneof access{ - IDPOAuthAccessInformation oauth = 1; + IDPOAuthAccessInformation oauth = 1 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "OAuth/OIDC access (and id_token) returned by the identity provider" + } + ]; } - bytes idp_information = 2; + string idp_id = 2 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "ID of the identity provider" + example: "\"d654e6ba-70a3-48ef-a95d-37c8d8a7901a\""; + } + ]; + string user_id = 3 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "ID of the user of the identity provider" + example: "\"6516849804890468048461403518\""; + } + ]; + string user_name = 4 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "username of the user of the identity provider" + example: "\"user@external.com\""; + } + ]; + google.protobuf.Struct raw_information = 5 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "complete information returned by the identity provider" + } + ]; } message IDPOAuthAccessInformation{ @@ -30,22 +57,22 @@ message IDPLink { example: "\"d654e6ba-70a3-48ef-a95d-37c8d8a7901a\""; } ]; - string idp_external_id = 2 [ + string user_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" + description: "ID of the user of the identity provider" min_length: 1; max_length: 200; - example: "\"d654e6ba-70a3-48ef-a95d-37c8d8a7901a\""; + example: "\"6516849804890468048461403518\""; } ]; - string display_name = 3 [ + string user_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" + description: "username of the user of the identity provider" min_length: 1; max_length: 200; - example: "\"Firstname Lastname\""; + example: "\"user@external.com\""; } ]; } diff --git a/proto/zitadel/user/v2alpha/password.proto b/proto/zitadel/user/v2alpha/password.proto index eb168f043..38089b0b0 100644 --- a/proto/zitadel/user/v2alpha/password.proto +++ b/proto/zitadel/user/v2alpha/password.proto @@ -8,13 +8,6 @@ import "google/api/field_behavior.proto"; import "protoc-gen-openapiv2/options/annotations.proto"; import "validate/validate.proto"; -message SetUserPassword { - oneof type { - Password password = 1; - HashedPassword hashed_password = 2; - } -} - message Password { string password = 1 [ (validate.rules).string = {min_len: 1, max_len: 200}, @@ -51,3 +44,24 @@ message HashedPassword { ]; bool change_required = 3; } + +message SendPasswordResetLink { + NotificationType notification_type = 1; + optional string url_template = 2 [ + (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/password/changey?userID={{.UserID}}&code={{.Code}}&orgID={{.OrgID}}\""; + description: "\"Optionally set a url_template, which will be used in the password reset mail sent by ZITADEL to guide the user to your password change page. If no template is set, the default ZITADEL url will be used.\"" + } + ]; +} + +message ReturnPasswordResetCode {} + +enum NotificationType { + NOTIFICATION_TYPE_Unspecified = 0; + NOTIFICATION_TYPE_Email = 1; + NOTIFICATION_TYPE_SMS = 2; +} diff --git a/proto/zitadel/user/v2alpha/user_service.proto b/proto/zitadel/user/v2alpha/user_service.proto index 9522cd96a..1534a4d74 100644 --- a/proto/zitadel/user/v2alpha/user_service.proto +++ b/proto/zitadel/user/v2alpha/user_service.proto @@ -225,6 +225,98 @@ service UserService { }; } + rpc RegisterU2F (RegisterU2FRequest) returns (RegisterU2FResponse) { + option (google.api.http) = { + post: "/v2alpha/users/{user_id}/u2f" + 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 a u2f token for a user"; + description: "Start the registration of a u2f token for a user, as a response the public key credential creation options are returned, which are used to verify the u2f token." + responses: { + key: "200" + value: { + description: "OK"; + } + }; + }; + } + + rpc VerifyU2FRegistration (VerifyU2FRegistrationRequest) returns (VerifyU2FRegistrationResponse) { + option (google.api.http) = { + post: "/v2alpha/users/{user_id}/u2f/{u2f_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 u2f token for a user"; + description: "Verify the u2f token registration with the public key credential." + responses: { + key: "200" + value: { + description: "OK"; + } + }; + }; + } + + rpc RegisterTOTP (RegisterTOTPRequest) returns (RegisterTOTPResponse) { + option (google.api.http) = { + post: "/v2alpha/users/{user_id}/totp" + 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 a TOTP generator for a user"; + description: "Start the registration of a TOTP generator for a user, as a response a secret returned, which is used to initialize a TOTP app or device." + responses: { + key: "200" + value: { + description: "OK"; + } + }; + }; + } + + rpc VerifyTOTPRegistration (VerifyTOTPRegistrationRequest) returns (VerifyTOTPRegistrationResponse) { + option (google.api.http) = { + post: "/v2alpha/users/{user_id}/totp/_verify" + body: "*" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "authenticated" + } + }; + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + summary: "Verify a TOTP generator for a user"; + description: "Verify the TOTP registration with a generated code." + 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) = { @@ -298,6 +390,80 @@ service UserService { }; }; } + + // Request password reset + rpc PasswordReset (PasswordResetRequest) returns (PasswordResetResponse) { + option (google.api.http) = { + post: "/v2alpha/users/{user_id}/password_reset" + body: "*" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "authenticated" + } + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + summary: "Request a code to reset a password"; + description: "Request a code to reset a password"; + responses: { + key: "200" + value: { + description: "OK"; + } + }; + }; + } + + // Change password + rpc SetPassword (SetPasswordRequest) returns (SetPasswordResponse) { + option (google.api.http) = { + post: "/v2alpha/users/{user_id}/password" + body: "*" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "authenticated" + } + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + summary: "Request a code to reset a password"; + description: "Request a code to reset a password"; + responses: { + key: "200" + value: { + description: "OK"; + } + }; + }; + } + + // List all possible authentication methods of a user + rpc ListAuthenticationMethodTypes (ListAuthenticationMethodTypesRequest) returns (ListAuthenticationMethodTypesResponse) { + option (google.api.http) = { + get: "/v2alpha/users/{user_id}/authentication_methods" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "authenticated" + } + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + summary: "List all possible authentication methods of a user"; + description: "List all possible authentication methods of a user like password, passwordless, (T)OTP and more"; + responses: { + key: "200" + value: { + description: "OK"; + } + }; + }; + } } message AddHumanUserRequest{ @@ -421,6 +587,11 @@ message RegisterPasskeyRequest{ description: "\"Optionally specify the authenticator type of the passkey device (platform or cross-platform). If none is provided, both values are allowed.\""; } ]; + string domain = 4 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "\"Domain on which the user is authenticated.\""; + } + ]; } message RegisterPasskeyResponse{ @@ -482,6 +653,132 @@ message VerifyPasskeyRegistrationResponse{ zitadel.object.v2alpha.Details details = 1; } +message RegisterU2FRequest{ + 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 domain = 2 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "\"Domain on which the user is authenticated.\""; + } + ]; +} + +message RegisterU2FResponse{ + zitadel.object.v2alpha.Details details = 1; + string u2f_id = 2 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"fabde5c8-c13f-481d-a90b-5e59a001a076\"" + } + ]; + google.protobuf.Struct public_key_credential_creation_options = 3 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "Options for Credential Creation (dictionary PublicKeyCredentialCreationOptions). Generated helper methods transform the field to JSON, for use in a WebauthN client. See also: https://www.w3.org/TR/webauthn/#dictdef-publickeycredentialcreationoptions" + example: "{\"publicKey\":{\"attestation\":\"none\",\"authenticatorSelection\":{\"userVerification\":\"required\"},\"challenge\":\"XaMYwWOZ5hj6pwtwJJlpcI-ExkO5TxevBMG4R8DoKQQ\",\"excludeCredentials\":[{\"id\":\"tVp1QfYhT8DkyEHVrv7blnpAo2YJzbZgZNBf7zPs6CI\",\"type\":\"public-key\"}],\"pubKeyCredParams\":[{\"alg\":-7,\"type\":\"public-key\"}],\"rp\":{\"id\":\"localhost\",\"name\":\"ZITADEL\"},\"timeout\":300000,\"user\":{\"displayName\":\"Tim Mohlmann\",\"id\":\"MjE1NTk4MDAwNDY0OTk4OTQw\",\"name\":\"tim\"}}}" + } + ]; +} + +message VerifyU2FRegistrationRequest{ + 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 u2f_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\""; + } + ]; + google.protobuf.Struct public_key_credential = 3 [ + (validate.rules).message.required = true, + (google.api.field_behavior) = REQUIRED, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "PublicKeyCredential Interface. Generated helper methods populate the field from JSON created by a WebauthN client. See also: https://www.w3.org/TR/webauthn/#publickeycredential"; + example: "{\"type\":\"public-key\",\"id\":\"pawVarF4xPxLFmfCnRkwXWeTrKGzabcAi92LEI1WC00\",\"rawId\":\"pawVarF4xPxLFmfCnRkwXWeTrKGzabcAi92LEI1WC00\",\"response\":{\"attestationObject\":\"o2NmbXRmcGFja2VkZ2F0dFN0bXSiY2FsZyZjc2lnWEcwRQIgRKS3VpeE9tfExXRzkoUKnG4rQWPvtSSt4YtDGgTx32oCIQDPey-2YJ4uIg-QCM4jj6aE2U3tgMFM_RP7Efx6xRu3JGhhdXRoRGF0YVikSZYN5YgOjGh0NBcPZHZgW4_krrmihjLHmVzzuoMdl2NFAAAAADju76085Yhmlt1CEOHkwLQAIKWsFWqxeMT8SxZnwp0ZMF1nk6yhs2m3AIvdixCNVgtNpQECAyYgASFYIMGUDSP2FAQn2MIfPMy7cyB_Y30VqixVgGULTBtFjfRiIlggjUGfQo3_-CrMmH3S-ZQkFKWKnNBQEAMkFtG-9A4zqW0\",\"clientDataJSON\":\"eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmdlIjoiQlhXdHh0WGxJeFZZa0pHT1dVaUVmM25zby02aXZKdWw2YmNmWHdMVlFIayIsIm9yaWdpbiI6Imh0dHBzOi8vbG9jYWxob3N0OjgwODAifQ\"}}"; + min_length: 55; + max_length: 1048576; //1 MB + } + ]; + string token_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 VerifyU2FRegistrationResponse{ + zitadel.object.v2alpha.Details details = 1; +} + +message RegisterTOTPRequest { + 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\""; + } + ]; +} + +message RegisterTOTPResponse { + zitadel.object.v2alpha.Details details = 1; + string uri = 2 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"otpauth://totp/ZITADEL:gigi@acme.zitadel.cloud?algorithm=SHA1&digits=6&issuer=ZITADEL&period=30&secret=TJOPWSDYILLHXFV4MLKNNJOWFG7VSDCK\""; + } + ]; + string secret = 3 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"TJOPWSDYILLHXFV4MLKNNJOWFG7VSDCK\""; + } + ]; +} + +message VerifyTOTPRegistrationRequest { + 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 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: "Code generated by TOTP app or device" + example: "\"123456\""; + } + ]; +} + +message VerifyTOTPRegistrationResponse { + zitadel.object.v2alpha.Details details = 1; +} + message CreatePasskeyRegistrationLinkRequest{ string user_id = 1 [ (validate.rules).string = {min_len: 1, max_len: 200}, @@ -593,3 +890,93 @@ message AddIDPLinkRequest{ message AddIDPLinkResponse { zitadel.object.v2alpha.Details details = 1; } + + +message PasswordResetRequest{ + 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\""; + } + ]; + // if no medium is specified, an email is sent with the default url + oneof medium { + SendPasswordResetLink send_link = 2; + ReturnPasswordResetCode return_code = 3; + } +} + +message PasswordResetResponse{ + zitadel.object.v2alpha.Details details = 1; + // in case the medium was set to return_code, the code will be returned + optional string verification_code = 2; +} + +message SetPasswordRequest{ + 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\""; + } + ]; + Password new_password = 2; + // if neither, the current password must be provided nor a verification code generated by the PasswordReset is provided, + // the user must be granted permission to set a password + oneof verification { + string current_password = 3 [ + (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: "\"Secr3tP4ssw0rd!\""; + } + ]; + string verification_code = 4 [ + (validate.rules).string = {min_len: 1, max_len: 20}, + (google.api.field_behavior) = REQUIRED, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + min_length: 1; + max_length: 20; + example: "\"SKJd342k\""; + description: "\"the verification code generated during password reset request\""; + } + ]; + } +} + +message SetPasswordResponse{ + zitadel.object.v2alpha.Details details = 1; +} + +message ListAuthenticationMethodTypesRequest{ + 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\""; + } + ]; +} + +message ListAuthenticationMethodTypesResponse{ + zitadel.object.v2alpha.ListDetails details = 1; + repeated AuthenticationMethodType auth_method_types = 2; +} + +enum AuthenticationMethodType { + AUTHENTICATION_METHOD_TYPE_UNSPECIFIED = 0; + AUTHENTICATION_METHOD_TYPE_PASSWORD = 1; + AUTHENTICATION_METHOD_TYPE_PASSKEY = 2; + AUTHENTICATION_METHOD_TYPE_IDP = 3; + AUTHENTICATION_METHOD_TYPE_TOTP = 4; + AUTHENTICATION_METHOD_TYPE_U2F = 5; +}