diff --git a/.github/workflows/zitadel.yml b/.github/workflows/zitadel.yml deleted file mode 100644 index ff30ce044..000000000 --- a/.github/workflows/zitadel.yml +++ /dev/null @@ -1,91 +0,0 @@ -name: Zitadel Release -on: push - -env: - GITHUB_TOKEN: ${{ secrets.CR_PAT }} - REGISTRY: ghcr.io - NODE_VERSION: '12' - GO_VERSION: '1.15' - -jobs: - container: - runs-on: ubuntu-18.04 - steps: - - name: Source checkout - uses: actions/checkout@v2 - - name: Set output - id: branch - run: echo ::set-output name=short_ref::${GITHUB_REF#refs/*/} - - name: Check output - run: echo ${{ steps.branch.outputs.short_ref }} - - name: Generate Short SHA Container Tag - id: vars - run: echo "::set-output name=sha_short::SHA-$(git rev-parse --short=12 HEAD)" - - name: Cache Docker layers - uses: actions/cache@v2 - with: - path: /tmp/.buildx-cache - key: ${{ runner.os }}-buildx-${{ github.sha }} - restore-keys: | - ${{ runner.os }}-buildx- - - name: Set up QEMU - uses: docker/setup-qemu-action@v1 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1 - - name: Login to DockerHub - uses: docker/login-action@v1 - with: - username: ${{ github.actor }} - password: ${{ secrets.CR_PAT }} - registry: ${{ env.REGISTRY }} - - uses: docker/build-push-action@v2 - with: - context: . - file: ./build/dockerfile - platforms: linux/amd64 - tags: ${{ env.REGISTRY }}/${{ github.repository }}:${{ steps.vars.outputs.sha_short }},${{ env.REGISTRY }}/${{ github.repository }}:${{ steps.branch.outputs.short_ref }} - push: true - cache-from: type=local,src=/tmp/.buildx-cache - cache-to: type=local,mode=max,dest=/tmp/.buildx-cache - - release: - runs-on: ubuntu-18.04 - needs: [container] - env: - DOCKER_USERNAME: ${{ github.actor }} - DOCKER_PASSWORD: ${{ secrets.CR_PAT }} - steps: - - name: Source checkout - uses: actions/checkout@v2 - - name: Generate Short SHA Container Tag - id: vars - run: echo "::set-output name=sha_short::SHA-$(git rev-parse --short=12 HEAD)" - - name: Docker Login - run: docker login $REGISTRY -u $GITHUB_ACTOR -p $GITHUB_TOKEN - - name: Docker Pull short-sha - run: docker pull $REGISTRY/$GITHUB_REPOSITORY:${{ steps.vars.outputs.sha_short }} - - name: Semantic Release - id: semantic - uses: cycjimmy/semantic-release-action@v2 - with: - dry_run: false - semantic_version: 17.0.4 - - name: Do something when a new release published - if: steps.semantic.outputs.new_release_published == 'true' - run: | - echo ${{ steps.semantic.outputs.new_release_version }} - echo ${{ steps.semantic.outputs.new_release_major_version }} - echo ${{ steps.semantic.outputs.new_release_minor_version }} - echo ${{ steps.semantic.outputs.new_release_patch_version }} - - name: Docker Tag Version - run: docker tag $REGISTRY/$GITHUB_REPOSITORY:${{ steps.vars.outputs.sha_short }} $REGISTRY/$GITHUB_REPOSITORY:${{ steps.semantic.outputs.new_release_version }} - if: steps.semantic.outputs.new_release_published == 'true' - - name: Docker Tag Latest - run: docker tag $REGISTRY/$GITHUB_REPOSITORY:${{ steps.vars.outputs.sha_short }} $REGISTRY/$GITHUB_REPOSITORY:latest - if: steps.semantic.outputs.new_release_published == 'true' - - name: Docker Push Version - run: docker push $REGISTRY/$GITHUB_REPOSITORY:${{ steps.semantic.outputs.new_release_version }} - if: steps.semantic.outputs.new_release_published == 'true' - - name: Docker Push Latest - run: docker push $REGISTRY/$GITHUB_REPOSITORY:latest - if: steps.semantic.outputs.new_release_published == 'true' diff --git a/.releaserc.js b/.releaserc.js index 4e06dce04..13f197971 100644 --- a/.releaserc.js +++ b/.releaserc.js @@ -6,15 +6,15 @@ module.exports = { ["@semantic-release/github", { "assets": [ { - "path": ".artifacts/zitadel-darwin-amd64/zitadelctl", + "path": "./artifacts/zitadelctl-darwin-amd64/zitadelctl-darwin-amd64", "label": "Zitadelctl Darwin x86_64" }, { - "path": ".artifacts/zitadel-linux-amd64/zitadelctl", + "path": "./artifacts/zitadelctl-linux-amd64/zitadelctl-linux-amd64", "label": "Zitadelctl Linux x86_64" }, { - "path": ".artifacts/zitadel-windows-amd64/zitadelctl", + "path": "./artifacts/zitadelctl-windows-amd64/zitadelctl-windows-amd64.exe", "label": "Zitadelctl Windows x86_64" } ] diff --git a/cmd/zitadel/setup.yaml b/cmd/zitadel/setup.yaml index ea627a4dd..9b499f361 100644 --- a/cmd/zitadel/setup.yaml +++ b/cmd/zitadel/setup.yaml @@ -88,7 +88,7 @@ SetUp: Step6: DefaultLabelPolicy: PrimaryColor: '#222324' - SecondaryColor: '#ffffff' + SecondaryColor: '#ffffff' Step7: OTP: true Step8: @@ -180,4 +180,4 @@ SetUp: Text: The domain {{.Domain}} has been claimed by an organisation. Your current user {{.Username}} is not part of this organisation. Therefore you'll have to change your email when you login. We have created a temporary username ({{.TempUsername}}) for this login. ButtonText: Login Step11: - MigrateV1EventstoreToV2: true + MigrateV1EventstoreToV2: $ZITADEL_MIGRATE_ES_V1 diff --git a/cmd/zitadel/startup.yaml b/cmd/zitadel/startup.yaml index 4a62c52bc..303874658 100644 --- a/cmd/zitadel/startup.yaml +++ b/cmd/zitadel/startup.yaml @@ -17,6 +17,7 @@ Metrics: MeterName: 'github.com/caos/zitadel' AuthZ: + Domain: $ZITADEL_DEFAULT_DOMAIN Repository: Eventstore: ServiceName: 'AuthZ' @@ -186,6 +187,7 @@ API: Issuer: $ZITADEL_ISSUER DefaultLogoutRedirectURI: $ZITADEL_ACCOUNTS/logout/done CodeMethodS256: true + AuthMethodPrivateKeyJWT: true StorageConfig: DefaultLoginURL: $ZITADEL_ACCOUNTS/login?authRequestID= DefaultAccessTokenLifetime: 12h @@ -207,6 +209,9 @@ API: Token: Path: 'token' URL: '$ZITADEL_OAUTH/token' + Introspection: + Path: 'introspect' + URL: '$ZITADEL_OAUTH/introspect' EndSession: Path: 'endsession' URL: '$ZITADEL_AUTHORIZE/endsession' diff --git a/cmd/zitadel/system-defaults.yaml b/cmd/zitadel/system-defaults.yaml index b2ecfc023..029925fa1 100644 --- a/cmd/zitadel/system-defaults.yaml +++ b/cmd/zitadel/system-defaults.yaml @@ -45,6 +45,7 @@ SystemDefaults: IncludeDigits: true IncludeSymbols: false MachineKeySize: 2048 + ClientKeySize: 2048 Multifactors: OTP: Issuer: 'ZITADEL' diff --git a/console/package-lock.json b/console/package-lock.json index a60b752e2..0f2f97ae5 100644 --- a/console/package-lock.json +++ b/console/package-lock.json @@ -4,43 +4,34 @@ "lockfileVersion": 1, "requires": true, "dependencies": { - "@angular-devkit/architect": { - "version": "0.1101.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1101.2.tgz", - "integrity": "sha512-MLmBfHiiyPhbFSSAX4oMecPjEuBauOui5uBpI6BKNnk/7783fznbkbAKjXlOco7M81gkNeEoHMR8c+mOfcvv7g==", - "dev": true, - "requires": { - "@angular-devkit/core": "11.1.2", - "rxjs": "6.6.3" - } - }, "@angular-devkit/build-angular": { - "version": "0.1101.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-0.1101.2.tgz", - "integrity": "sha512-EVJ7kAgy+sMnliCmHwN1niVeM7YaAvTMkF+ahImNfQRSQOW+QJ4F8vjiLtuARC6R02Yc5QPzELTHVPxC4Qll/A==", + "version": "0.1102.0", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-0.1102.0.tgz", + "integrity": "sha512-9Yl6qBOR1o0ThyLhrWJ6Rhr3qLRe+RP3sbfUt4QA+8wsIXN7WakEXJALlq7TDeG66OaWyyjbtC2q3EPdNeBC/g==", "dev": true, "requires": { - "@angular-devkit/architect": "0.1101.2", - "@angular-devkit/build-optimizer": "0.1101.2", - "@angular-devkit/build-webpack": "0.1101.2", - "@angular-devkit/core": "11.1.2", + "@angular-devkit/architect": "0.1102.0", + "@angular-devkit/build-optimizer": "0.1102.0", + "@angular-devkit/build-webpack": "0.1102.0", + "@angular-devkit/core": "11.2.0", "@babel/core": "7.12.10", "@babel/generator": "7.12.11", + "@babel/plugin-transform-async-to-generator": "7.12.1", "@babel/plugin-transform-runtime": "7.12.10", "@babel/preset-env": "7.12.11", "@babel/runtime": "7.12.5", "@babel/template": "7.12.7", "@jsdevtools/coverage-istanbul-loader": "3.0.5", - "@ngtools/webpack": "11.1.2", + "@ngtools/webpack": "11.2.0", "ansi-colors": "4.1.1", - "autoprefixer": "10.2.1", + "autoprefixer": "10.2.4", "babel-loader": "8.2.2", "browserslist": "^4.9.1", "cacache": "15.0.5", "caniuse-lite": "^1.0.30001032", "circular-dependency-plugin": "5.2.2", "copy-webpack-plugin": "6.3.2", - "core-js": "3.8.2", + "core-js": "3.8.3", "critters": "0.0.6", "css-loader": "5.0.1", "cssnano": "4.1.10", @@ -51,14 +42,14 @@ "inquirer": "7.3.3", "jest-worker": "26.6.2", "karma-source-map-support": "1.4.0", - "less": "4.1.0", + "less": "4.1.1", "less-loader": "7.3.0", "license-webpack-plugin": "2.3.11", "loader-utils": "2.0.0", - "mini-css-extract-plugin": "1.3.3", + "mini-css-extract-plugin": "1.3.5", "minimatch": "3.0.4", - "open": "7.3.1", - "ora": "5.2.0", + "open": "7.4.0", + "ora": "5.3.0", "parse5-html-rewriting-stream": "6.0.1", "pnp-webpack-plugin": "1.6.4", "postcss": "8.2.4", @@ -68,38 +59,61 @@ "regenerator-runtime": "0.13.7", "resolve-url-loader": "3.1.2", "rimraf": "3.0.2", - "rollup": "2.36.1", + "rollup": "2.38.4", "rxjs": "6.6.3", - "sass": "1.32.4", + "sass": "1.32.6", "sass-loader": "10.1.1", "semver": "7.3.4", "source-map": "0.7.3", "source-map-loader": "1.1.3", "source-map-support": "0.5.19", - "speed-measure-webpack-plugin": "1.3.3", + "speed-measure-webpack-plugin": "1.4.2", "style-loader": "2.0.0", "stylus": "0.54.8", - "stylus-loader": "4.3.2", + "stylus-loader": "4.3.3", "terser": "5.5.1", "terser-webpack-plugin": "4.2.3", "text-table": "0.2.0", "tree-kill": "1.2.2", "webpack": "4.44.2", "webpack-dev-middleware": "3.7.2", - "webpack-dev-server": "3.11.1", + "webpack-dev-server": "3.11.2", "webpack-merge": "5.7.3", "webpack-sources": "2.2.0", "webpack-subresource-integrity": "1.5.2", "worker-plugin": "5.0.0" }, "dependencies": { - "@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "@angular-devkit/architect": { + "version": "0.1102.0", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1102.0.tgz", + "integrity": "sha512-d9Da6SiTiDb5N1avxWLcPHSyWCq3G62TlROXxr32WkcQRko8wtgW5VOzgSkdmY2p6UTSME89naUojfzgu2Wh6g==", "dev": true, "requires": { - "@babel/highlight": "^7.10.4" + "@angular-devkit/core": "11.2.0", + "rxjs": "6.6.3" + } + }, + "@angular-devkit/core": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-11.2.0.tgz", + "integrity": "sha512-qqYEH8m/bwpngoLDMFuth8ykvoHxQ3aHHnAWfRXz9NXydwSfathG0VSYCctB126sK39JKIn+xq16CQAExxNu+Q==", + "dev": true, + "requires": { + "ajv": "6.12.6", + "fast-json-stable-stringify": "2.1.0", + "magic-string": "0.25.7", + "rxjs": "6.6.3", + "source-map": "0.7.3" + } + }, + "@babel/code-frame": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", + "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.12.13" } }, "@babel/core": { @@ -159,125 +173,170 @@ } }, "@babel/helper-function-name": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", - "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz", + "integrity": "sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.12.10", - "@babel/template": "^7.12.7", - "@babel/types": "^7.12.11" + "@babel/helper-get-function-arity": "^7.12.13", + "@babel/template": "^7.12.13", + "@babel/types": "^7.12.13" + }, + "dependencies": { + "@babel/template": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", + "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@babel/parser": "^7.12.13", + "@babel/types": "^7.12.13" + } + } } }, "@babel/helper-get-function-arity": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", - "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", + "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", "dev": true, "requires": { - "@babel/types": "^7.12.10" + "@babel/types": "^7.12.13" } }, "@babel/helper-member-expression-to-functions": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", - "integrity": "sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw==", + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.16.tgz", + "integrity": "sha512-zYoZC1uvebBFmj1wFAlXwt35JLEgecefATtKp20xalwEK8vHAixLBXTGxNrVGEmTT+gzOThUgr8UEdgtalc1BQ==", "dev": true, "requires": { - "@babel/types": "^7.12.7" + "@babel/types": "^7.12.13" } }, "@babel/helper-module-imports": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz", - "integrity": "sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.13.tgz", + "integrity": "sha512-NGmfvRp9Rqxy0uHSSVP+SRIW1q31a7Ji10cLBcqSDUngGentY4FRiHOFZFE1CLU5eiL0oE8reH7Tg1y99TDM/g==", "dev": true, "requires": { - "@babel/types": "^7.12.5" + "@babel/types": "^7.12.13" } }, "@babel/helper-module-transforms": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz", - "integrity": "sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.13.tgz", + "integrity": "sha512-acKF7EjqOR67ASIlDTupwkKM1eUisNAjaSduo5Cz+793ikfnpe7p4Q7B7EWU2PCoSTPWsQkR7hRUWEIZPiVLGA==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.12.1", - "@babel/helper-replace-supers": "^7.12.1", - "@babel/helper-simple-access": "^7.12.1", - "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/helper-validator-identifier": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.12.1", - "@babel/types": "^7.12.1", + "@babel/helper-module-imports": "^7.12.13", + "@babel/helper-replace-supers": "^7.12.13", + "@babel/helper-simple-access": "^7.12.13", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/helper-validator-identifier": "^7.12.11", + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.12.13", + "@babel/types": "^7.12.13", "lodash": "^4.17.19" + }, + "dependencies": { + "@babel/template": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", + "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@babel/parser": "^7.12.13", + "@babel/types": "^7.12.13" + } + } } }, "@babel/helper-optimise-call-expression": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz", - "integrity": "sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz", + "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==", "dev": true, "requires": { - "@babel/types": "^7.12.10" + "@babel/types": "^7.12.13" } }, "@babel/helper-replace-supers": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz", - "integrity": "sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.13.tgz", + "integrity": "sha512-pctAOIAMVStI2TMLhozPKbf5yTEXc0OJa0eENheb4w09SrgOWEs+P4nTOZYJQCqs8JlErGLDPDJTiGIp3ygbLg==", "dev": true, "requires": { - "@babel/helper-member-expression-to-functions": "^7.12.7", - "@babel/helper-optimise-call-expression": "^7.12.10", - "@babel/traverse": "^7.12.10", - "@babel/types": "^7.12.11" + "@babel/helper-member-expression-to-functions": "^7.12.13", + "@babel/helper-optimise-call-expression": "^7.12.13", + "@babel/traverse": "^7.12.13", + "@babel/types": "^7.12.13" } }, "@babel/helper-simple-access": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.1.tgz", - "integrity": "sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.13.tgz", + "integrity": "sha512-0ski5dyYIHEfwpWGx5GPWhH35j342JaflmCeQmsPWcrOQDtCN6C1zKAVRFVbK53lPW2c9TsuLLSUDf0tIGJ5hA==", "dev": true, "requires": { - "@babel/types": "^7.12.1" + "@babel/types": "^7.12.13" } }, "@babel/helper-split-export-declaration": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", - "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", + "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", "dev": true, "requires": { - "@babel/types": "^7.12.11" + "@babel/types": "^7.12.13" } }, + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + }, "@babel/helpers": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.12.5.tgz", - "integrity": "sha512-lgKGMQlKqA8meJqKsW6rUnc4MdUk35Ln0ATDqdM1a/UpARODdI4j5Y5lVfUScnSNkJcdCRAaWkspykNoFg9sJA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.12.13.tgz", + "integrity": "sha512-oohVzLRZ3GQEk4Cjhfs9YkJA4TdIDTObdBEZGrd6F/T0GPSnuV6l22eMcxlvcvzVIPH3VTtxbseudM1zIE+rPQ==", "dev": true, "requires": { - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.12.5", - "@babel/types": "^7.12.5" + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.12.13", + "@babel/types": "^7.12.13" + }, + "dependencies": { + "@babel/template": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", + "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@babel/parser": "^7.12.13", + "@babel/types": "^7.12.13" + } + } } }, "@babel/highlight": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", - "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.12.13.tgz", + "integrity": "sha512-kocDQvIbgMKlWxXe9fof3TQ+gkIPOUSEYhJjqUjvKMez3krV7vbzYCDq39Oj11UAVK7JqPVGQPlgE85dPNlQww==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/helper-validator-identifier": "^7.12.11", "chalk": "^2.0.0", "js-tokens": "^4.0.0" } }, "@babel/parser": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", - "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.16.tgz", + "integrity": "sha512-c/+u9cqV6F0+4Hpq01jnJO+GLp2DdT63ppz9Xa+6cHaajM9VFzK/iDXiKK65YtpeVwu+ctfS6iqlMqRgQRzeCw==", "dev": true }, "@babel/template": { @@ -292,39 +351,50 @@ } }, "@babel/traverse": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", - "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.13.tgz", + "integrity": "sha512-3Zb4w7eE/OslI0fTp8c7b286/cQps3+vdLW3UcwC8VSJC6GbKn55aeVVu2QJNuCDoeKyptLOFrPq8WqZZBodyA==", "dev": true, "requires": { - "@babel/code-frame": "^7.12.11", - "@babel/generator": "^7.12.11", - "@babel/helper-function-name": "^7.12.11", - "@babel/helper-split-export-declaration": "^7.12.11", - "@babel/parser": "^7.12.11", - "@babel/types": "^7.12.12", + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.12.13", + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/parser": "^7.12.13", + "@babel/types": "^7.12.13", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.19" + }, + "dependencies": { + "@babel/generator": { + "version": "7.12.15", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.15.tgz", + "integrity": "sha512-6F2xHxBiFXWNSGb7vyCUTBF8RCLY66rS0zEPcP8t/nQyXjha5EuK4z7H5o7fWG8B4M7y6mqVWq1J+1PuwRhecQ==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } } }, "@babel/types": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", - "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.13.tgz", + "integrity": "sha512-oKrdZTld2im1z8bDwTOQvUbxKwE+854zc16qWZQlcTqMN00pWxHQ4ZeOq0yDMnisOpRykH2/5Qqcrk/OlbAjiQ==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", "to-fast-properties": "^2.0.0" - }, - "dependencies": { - "@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", - "dev": true - } } }, "agent-base": { @@ -336,14 +406,41 @@ "debug": "4" } }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, "autoprefixer": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.2.1.tgz", - "integrity": "sha512-dwP0UjyYvROUvtU+boBx8ff5pPWami1NGTrJs9YUsS/oZVbRAcdNHOOuXSA1fc46tgKqe072cVaKD69rvCc3QQ==", + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.2.4.tgz", + "integrity": "sha512-DCCdUQiMD+P/as8m3XkeTUkUKuuRqLGcwD0nll7wevhqoJfMRpJlkFd1+MQh1pvupjiQuip42lc/VFvfUTMSKw==", "dev": true, "requires": { "browserslist": "^4.16.1", - "caniuse-lite": "^1.0.30001173", + "caniuse-lite": "^1.0.30001181", "colorette": "^1.2.1", "fraction.js": "^4.0.13", "normalize-range": "^0.1.2", @@ -364,13 +461,28 @@ } }, "caniuse-lite": { - "version": "1.0.30001181", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001181.tgz", - "integrity": "sha512-m5ul/ARCX50JB8BSNM+oiPmQrR5UmngaQ3QThTTp5HcIIQGP/nPBs82BYLE+tigzm3VW+F4BJIhUyaVtEweelQ==", + "version": "1.0.30001187", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001187.tgz", + "integrity": "sha512-w7/EP1JRZ9552CyrThUnay2RkZ1DXxKe/Q2swTC4+LElLh9RRYrL1Z+27LlakB8kzY0fSmHw9mc7XYDUKAKWMA==", "dev": true } } }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "debug": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", @@ -381,9 +493,9 @@ } }, "electron-to-chromium": { - "version": "1.3.649", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.649.tgz", - "integrity": "sha512-ojGDupQ3UMkvPWcTICe4JYe17+o9OLiFMPoduoR72Zp2ILt1mRVeqnxBEd6s/ptekrnsFU+0A4lStfBe/wyG/A==", + "version": "1.3.664", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.664.tgz", + "integrity": "sha512-yb8LrTQXQnh9yhnaIHLk6CYugF/An50T20+X0h++hjjhVfgSp1DGoMSYycF8/aD5eiqS4QwaNhiduFvK8rifRg==", "dev": true }, "escalade": { @@ -392,6 +504,12 @@ "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", "dev": true }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, "https-proxy-agent": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", @@ -408,6 +526,44 @@ "integrity": "sha512-Slf2s69+2/uAD79pVVQo8uSiC34+g8GWY8UH2Qtqv34ZfhYrxpYpfzs9Js9d6O0mbDmALuxaTlplnBTnSELcrw==", "dev": true }, + "open": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/open/-/open-7.4.0.tgz", + "integrity": "sha512-PGoBCX/lclIWlpS/R2PQuIR4NJoXh6X5AwVzE7WXnWRGvHg7+4TBCgsujUgiPpm0K1y4qvQeWnCWVTpTKZBtvA==", + "dev": true, + "requires": { + "is-docker": "^2.0.0", + "is-wsl": "^2.1.1" + } + }, + "ora": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.3.0.tgz", + "integrity": "sha512-zAKMgGXUim0Jyd6CXK9lraBnD3H5yPGBPPOkC23a2BG6hsm4Zu6OQSjQuEtV0BHDf4aKHcUFvJiGRrFuW3MG8g==", + "dev": true, + "requires": { + "bl": "^4.0.3", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "log-symbols": "^4.0.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "dependencies": { + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, "postcss": { "version": "8.2.4", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.2.4.tgz", @@ -450,13 +606,31 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", "dev": true + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } } } }, "@angular-devkit/build-optimizer": { - "version": "0.1101.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-optimizer/-/build-optimizer-0.1101.2.tgz", - "integrity": "sha512-ARcUcEwaAR3n0gUq2hCx4eXONdnKKXTYSaw2GUHtraBDp+m/vFcE6Ufxyki453eHbHtaQ9yjXOcBqu86u1u8hA==", + "version": "0.1102.0", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-optimizer/-/build-optimizer-0.1102.0.tgz", + "integrity": "sha512-0Xb7xR0iUrbo/BnKJPTsy5IuodfFUWbvXUu9qeKc+oHzwxObX4Y32X0yyRpIJc5UK7Ce43HkopRQ/tHdoJp2fQ==", "dev": true, "requires": { "loader-utils": "2.0.0", @@ -487,29 +661,39 @@ } }, "@angular-devkit/build-webpack": { - "version": "0.1101.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1101.2.tgz", - "integrity": "sha512-T8+LjKdxk1faQA4Dh3PYkRbIBLE6Tjv5SNZmdDXpvGoyxS9FmLgLDXQZqXkYgiAHwH6PxhoQX4iVxkHHFkkHog==", + "version": "0.1102.0", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1102.0.tgz", + "integrity": "sha512-bfd6WlxcbWJ01HNNcFt4sBBaY+Bz2J/zFA6BSORvC5LpqawYCYeUbDJTY9Wb7gtp+aPEiNHI0HeUvoNkubsYfg==", "dev": true, "requires": { - "@angular-devkit/architect": "0.1101.2", - "@angular-devkit/core": "11.1.2", + "@angular-devkit/architect": "0.1102.0", + "@angular-devkit/core": "11.2.0", "rxjs": "6.6.3" - } - }, - "@angular-devkit/core": { - "version": "11.1.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-11.1.2.tgz", - "integrity": "sha512-V7zOMqL2l56JcwXVyswkG+7+t67r9XtkrVzRcG2Z5ZYwafU+iKWMwg5kBFZr1SX7fM1M9E4MpskxqtagQeUKng==", - "dev": true, - "requires": { - "ajv": "6.12.6", - "fast-json-stable-stringify": "2.1.0", - "magic-string": "0.25.7", - "rxjs": "6.6.3", - "source-map": "0.7.3" }, "dependencies": { + "@angular-devkit/architect": { + "version": "0.1102.0", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1102.0.tgz", + "integrity": "sha512-d9Da6SiTiDb5N1avxWLcPHSyWCq3G62TlROXxr32WkcQRko8wtgW5VOzgSkdmY2p6UTSME89naUojfzgu2Wh6g==", + "dev": true, + "requires": { + "@angular-devkit/core": "11.2.0", + "rxjs": "6.6.3" + } + }, + "@angular-devkit/core": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-11.2.0.tgz", + "integrity": "sha512-qqYEH8m/bwpngoLDMFuth8ykvoHxQ3aHHnAWfRXz9NXydwSfathG0VSYCctB126sK39JKIn+xq16CQAExxNu+Q==", + "dev": true, + "requires": { + "ajv": "6.12.6", + "fast-json-stable-stringify": "2.1.0", + "magic-string": "0.25.7", + "rxjs": "6.6.3", + "source-map": "0.7.3" + } + }, "ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -531,14 +715,127 @@ } }, "@angular-devkit/schematics": { - "version": "11.1.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-11.1.2.tgz", - "integrity": "sha512-wIWI4+EPsjbN+23Rs0zE4GarKrUm8gMR3MpGAtlEmGG2ZsXEVdfiKUebBdWGrx0sEfgLN9JfePbZQFvqN5ifyw==", + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-11.2.0.tgz", + "integrity": "sha512-sMDacACJbA4pykiqgJf/RdW0damcf4mDqErGgEqs/bGG+SBUb8+wgt4cQnUwwVX5V2nMdvv7f0A84rgR6I3G2w==", "dev": true, "requires": { - "@angular-devkit/core": "11.1.2", - "ora": "5.2.0", + "@angular-devkit/core": "11.2.0", + "ora": "5.3.0", "rxjs": "6.6.3" + }, + "dependencies": { + "@angular-devkit/core": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-11.2.0.tgz", + "integrity": "sha512-qqYEH8m/bwpngoLDMFuth8ykvoHxQ3aHHnAWfRXz9NXydwSfathG0VSYCctB126sK39JKIn+xq16CQAExxNu+Q==", + "dev": true, + "requires": { + "ajv": "6.12.6", + "fast-json-stable-stringify": "2.1.0", + "magic-string": "0.25.7", + "rxjs": "6.6.3", + "source-map": "0.7.3" + } + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "ora": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.3.0.tgz", + "integrity": "sha512-zAKMgGXUim0Jyd6CXK9lraBnD3H5yPGBPPOkC23a2BG6hsm4Zu6OQSjQuEtV0BHDf4aKHcUFvJiGRrFuW3MG8g==", + "dev": true, + "requires": { + "bl": "^4.0.3", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "log-symbols": "^4.0.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + } + }, + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "@angular/animations": { @@ -559,16 +856,16 @@ } }, "@angular/cli": { - "version": "11.1.2", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-11.1.2.tgz", - "integrity": "sha512-qOAkxCzBPm+QdXpSHxLERw1Vag8S0JHMY0zCwtG63XFvwHZCIihHRkOR3xHDWlVnGTmnUixg4Mt5s/4GGPuDJg==", + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-11.2.0.tgz", + "integrity": "sha512-waIR5Nqc2wcYXZh/Mgm+4Iyvu0nzKAhvmKiJjcJ+f2UuPRMLdNAInTvhdpfgKaNdmiArxNa6UntRIu+EavGc9Q==", "dev": true, "requires": { - "@angular-devkit/architect": "0.1101.2", - "@angular-devkit/core": "11.1.2", - "@angular-devkit/schematics": "11.1.2", - "@schematics/angular": "11.1.2", - "@schematics/update": "0.1101.2", + "@angular-devkit/architect": "0.1102.0", + "@angular-devkit/core": "11.2.0", + "@angular-devkit/schematics": "11.2.0", + "@schematics/angular": "11.2.0", + "@schematics/update": "0.1102.0", "@yarnpkg/lockfile": "1.1.0", "ansi-colors": "4.1.1", "debug": "4.3.1", @@ -577,8 +874,9 @@ "jsonc-parser": "3.0.0", "npm-package-arg": "8.1.0", "npm-pick-manifest": "6.1.0", - "open": "7.3.1", - "pacote": "11.1.14", + "open": "7.4.0", + "ora": "5.3.0", + "pacote": "11.2.4", "resolve": "1.19.0", "rimraf": "3.0.2", "semver": "7.3.4", @@ -587,6 +885,81 @@ "uuid": "8.3.2" }, "dependencies": { + "@angular-devkit/architect": { + "version": "0.1102.0", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1102.0.tgz", + "integrity": "sha512-d9Da6SiTiDb5N1avxWLcPHSyWCq3G62TlROXxr32WkcQRko8wtgW5VOzgSkdmY2p6UTSME89naUojfzgu2Wh6g==", + "dev": true, + "requires": { + "@angular-devkit/core": "11.2.0", + "rxjs": "6.6.3" + } + }, + "@angular-devkit/core": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-11.2.0.tgz", + "integrity": "sha512-qqYEH8m/bwpngoLDMFuth8ykvoHxQ3aHHnAWfRXz9NXydwSfathG0VSYCctB126sK39JKIn+xq16CQAExxNu+Q==", + "dev": true, + "requires": { + "ajv": "6.12.6", + "fast-json-stable-stringify": "2.1.0", + "magic-string": "0.25.7", + "rxjs": "6.6.3", + "source-map": "0.7.3" + } + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "debug": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", @@ -596,12 +969,44 @@ "ms": "2.1.2" } }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, "ini": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", "dev": true }, + "open": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/open/-/open-7.4.0.tgz", + "integrity": "sha512-PGoBCX/lclIWlpS/R2PQuIR4NJoXh6X5AwVzE7WXnWRGvHg7+4TBCgsujUgiPpm0K1y4qvQeWnCWVTpTKZBtvA==", + "dev": true, + "requires": { + "is-docker": "^2.0.0", + "is-wsl": "^2.1.1" + } + }, + "ora": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.3.0.tgz", + "integrity": "sha512-zAKMgGXUim0Jyd6CXK9lraBnD3H5yPGBPPOkC23a2BG6hsm4Zu6OQSjQuEtV0BHDf4aKHcUFvJiGRrFuW3MG8g==", + "dev": true, + "requires": { + "bl": "^4.0.3", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "log-symbols": "^4.0.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + } + }, "resolve": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", @@ -629,6 +1034,30 @@ "requires": { "lru-cache": "^6.0.0" } + }, + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } } } }, @@ -831,9 +1260,9 @@ } }, "@angular/language-service": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-11.1.1.tgz", - "integrity": "sha512-87PYlTBBaMr0DYMYxkyeFas1qXIRYM0soNYkXC8yE+hxkGWTN15Zjk19+lx5z43++uNOiZw1mqnKTJoO46kE6A==", + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-11.2.0.tgz", + "integrity": "sha512-0n7yrBiwpN6qUEDBoMHxEzxRN+w4tIe+42Ra68UQ5leBx5mSA6P6Ipi+nPwy8RXjqNEHgR0D//30Zp18O8UhCA==", "dev": true }, "@angular/material": { @@ -894,9 +1323,9 @@ } }, "@babel/compat-data": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.12.7.tgz", - "integrity": "sha512-YaxPMGs/XIWtYqrdEOZOCPsVWfEoriXopnsz3/i7apYPXQ3698UFhS6dVT1KN5qOsWmVgw/FOrmQgpRaZayGsw==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.12.13.tgz", + "integrity": "sha512-U/hshG5R+SIoW7HVWIdmy1cB7s3ki+r3FpyEZiCgpi4tFgPnX/vynY80ZGSASOIrUM6O7VxOgCZgdt7h97bUGg==", "dev": true }, "@babel/core": { @@ -961,12 +1390,12 @@ } }, "@babel/helper-annotate-as-pure": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.10.tgz", - "integrity": "sha512-XplmVbC1n+KY6jL8/fgLVXXUauDIB+lD5+GsQEh6F6GBF1dq1qy4DP4yXWzDKcoqXB3X58t61e85Fitoww4JVQ==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.13.tgz", + "integrity": "sha512-7YXfX5wQ5aYM/BOlbSccHDbuXXFPxeoUmfWtz8le2yTkTZc+BxsiEnENFoi2SlmA8ewDkG2LgIMIVzzn2h8kfw==", "dev": true, "requires": { - "@babel/types": "^7.12.10" + "@babel/types": "^7.12.13" }, "dependencies": { "@babel/helper-validator-identifier": { @@ -976,9 +1405,9 @@ "dev": true }, "@babel/types": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", - "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.13.tgz", + "integrity": "sha512-oKrdZTld2im1z8bDwTOQvUbxKwE+854zc16qWZQlcTqMN00pWxHQ4ZeOq0yDMnisOpRykH2/5Qqcrk/OlbAjiQ==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", @@ -989,23 +1418,42 @@ } }, "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.4.tgz", - "integrity": "sha512-L0zGlFrGWZK4PbT8AszSfLTM5sDU1+Az/En9VrdT8/LmEiJt4zXt+Jve9DCAnQcbqDhCI+29y/L93mrDzddCcg==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.12.13.tgz", + "integrity": "sha512-CZOv9tGphhDRlVjVkAgm8Nhklm9RzSmWpX2my+t7Ua/KT616pEzXsQCjinzvkRvHWJ9itO4f296efroX23XCMA==", "dev": true, "requires": { - "@babel/helper-explode-assignable-expression": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/helper-explode-assignable-expression": "^7.12.13", + "@babel/types": "^7.12.13" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + }, + "@babel/types": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.13.tgz", + "integrity": "sha512-oKrdZTld2im1z8bDwTOQvUbxKwE+854zc16qWZQlcTqMN00pWxHQ4ZeOq0yDMnisOpRykH2/5Qqcrk/OlbAjiQ==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.12.11", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-compilation-targets": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.12.5.tgz", - "integrity": "sha512-+qH6NrscMolUlzOYngSBMIOQpKUGPPsc61Bu5W10mg84LxZ7cmvnBHzARKbDoFxVvqqAbj6Tg6N7bSrWSPXMyw==", + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.12.16.tgz", + "integrity": "sha512-dBHNEEaZx7F3KoUYqagIhRIeqyyuI65xMndMZ3WwGwEBI609I4TleYQHcrS627vbKyNTXqShoN+fvYD9HuQxAg==", "dev": true, "requires": { - "@babel/compat-data": "^7.12.5", - "@babel/helper-validator-option": "^7.12.1", + "@babel/compat-data": "^7.12.13", + "@babel/helper-validator-option": "^7.12.16", "browserslist": "^4.14.5", "semver": "^5.5.0" }, @@ -1024,15 +1472,15 @@ } }, "caniuse-lite": { - "version": "1.0.30001181", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001181.tgz", - "integrity": "sha512-m5ul/ARCX50JB8BSNM+oiPmQrR5UmngaQ3QThTTp5HcIIQGP/nPBs82BYLE+tigzm3VW+F4BJIhUyaVtEweelQ==", + "version": "1.0.30001187", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001187.tgz", + "integrity": "sha512-w7/EP1JRZ9552CyrThUnay2RkZ1DXxKe/Q2swTC4+LElLh9RRYrL1Z+27LlakB8kzY0fSmHw9mc7XYDUKAKWMA==", "dev": true }, "electron-to-chromium": { - "version": "1.3.649", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.649.tgz", - "integrity": "sha512-ojGDupQ3UMkvPWcTICe4JYe17+o9OLiFMPoduoR72Zp2ILt1mRVeqnxBEd6s/ptekrnsFU+0A4lStfBe/wyG/A==", + "version": "1.3.664", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.664.tgz", + "integrity": "sha512-yb8LrTQXQnh9yhnaIHLk6CYugF/An50T20+X0h++hjjhVfgSp1DGoMSYycF8/aD5eiqS4QwaNhiduFvK8rifRg==", "dev": true }, "escalade": { @@ -1050,77 +1498,95 @@ } }, "@babel/helper-create-class-features-plugin": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.12.1.tgz", - "integrity": "sha512-hkL++rWeta/OVOBTRJc9a5Azh5mt5WgZUGAKMD8JM141YsE08K//bp1unBBieO6rUKkIPyUE0USQ30jAy3Sk1w==", + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.12.16.tgz", + "integrity": "sha512-KbSEj8l9zYkMVHpQqM3wJNxS1d9h3U9vm/uE5tpjMbaj3lTp+0noe3KPsV5dSD9jxKnf9jO9Ip9FX5PKNZCKow==", "dev": true, "requires": { - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-member-expression-to-functions": "^7.12.1", - "@babel/helper-optimise-call-expression": "^7.10.4", - "@babel/helper-replace-supers": "^7.12.1", - "@babel/helper-split-export-declaration": "^7.10.4" + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-member-expression-to-functions": "^7.12.16", + "@babel/helper-optimise-call-expression": "^7.12.13", + "@babel/helper-replace-supers": "^7.12.13", + "@babel/helper-split-export-declaration": "^7.12.13" }, "dependencies": { "@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", + "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", "dev": true, "requires": { - "@babel/highlight": "^7.10.4" + "@babel/highlight": "^7.12.13" } }, "@babel/generator": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", - "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", + "version": "7.12.15", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.15.tgz", + "integrity": "sha512-6F2xHxBiFXWNSGb7vyCUTBF8RCLY66rS0zEPcP8t/nQyXjha5EuK4z7H5o7fWG8B4M7y6mqVWq1J+1PuwRhecQ==", "dev": true, "requires": { - "@babel/types": "^7.12.11", + "@babel/types": "^7.12.13", "jsesc": "^2.5.1", "source-map": "^0.5.0" } }, - "@babel/helper-get-function-arity": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", - "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", + "@babel/helper-function-name": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz", + "integrity": "sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==", "dev": true, "requires": { - "@babel/types": "^7.12.10" + "@babel/helper-get-function-arity": "^7.12.13", + "@babel/template": "^7.12.13", + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", + "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13" } }, "@babel/helper-member-expression-to-functions": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", - "integrity": "sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw==", + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.16.tgz", + "integrity": "sha512-zYoZC1uvebBFmj1wFAlXwt35JLEgecefATtKp20xalwEK8vHAixLBXTGxNrVGEmTT+gzOThUgr8UEdgtalc1BQ==", "dev": true, "requires": { - "@babel/types": "^7.12.7" + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz", + "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13" } }, "@babel/helper-replace-supers": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz", - "integrity": "sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.13.tgz", + "integrity": "sha512-pctAOIAMVStI2TMLhozPKbf5yTEXc0OJa0eENheb4w09SrgOWEs+P4nTOZYJQCqs8JlErGLDPDJTiGIp3ygbLg==", "dev": true, "requires": { - "@babel/helper-member-expression-to-functions": "^7.12.7", - "@babel/helper-optimise-call-expression": "^7.12.10", - "@babel/traverse": "^7.12.10", - "@babel/types": "^7.12.11" - }, - "dependencies": { - "@babel/helper-optimise-call-expression": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz", - "integrity": "sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ==", - "dev": true, - "requires": { - "@babel/types": "^7.12.10" - } - } + "@babel/helper-member-expression-to-functions": "^7.12.13", + "@babel/helper-optimise-call-expression": "^7.12.13", + "@babel/traverse": "^7.12.13", + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", + "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13" } }, "@babel/helper-validator-identifier": { @@ -1130,76 +1596,54 @@ "dev": true }, "@babel/highlight": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", - "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.12.13.tgz", + "integrity": "sha512-kocDQvIbgMKlWxXe9fof3TQ+gkIPOUSEYhJjqUjvKMez3krV7vbzYCDq39Oj11UAVK7JqPVGQPlgE85dPNlQww==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/helper-validator-identifier": "^7.12.11", "chalk": "^2.0.0", "js-tokens": "^4.0.0" } }, "@babel/parser": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", - "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.16.tgz", + "integrity": "sha512-c/+u9cqV6F0+4Hpq01jnJO+GLp2DdT63ppz9Xa+6cHaajM9VFzK/iDXiKK65YtpeVwu+ctfS6iqlMqRgQRzeCw==", "dev": true }, "@babel/template": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", - "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", + "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", "dev": true, "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/parser": "^7.12.7", - "@babel/types": "^7.12.7" + "@babel/code-frame": "^7.12.13", + "@babel/parser": "^7.12.13", + "@babel/types": "^7.12.13" } }, "@babel/traverse": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", - "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.13.tgz", + "integrity": "sha512-3Zb4w7eE/OslI0fTp8c7b286/cQps3+vdLW3UcwC8VSJC6GbKn55aeVVu2QJNuCDoeKyptLOFrPq8WqZZBodyA==", "dev": true, "requires": { - "@babel/code-frame": "^7.12.11", - "@babel/generator": "^7.12.11", - "@babel/helper-function-name": "^7.12.11", - "@babel/helper-split-export-declaration": "^7.12.11", - "@babel/parser": "^7.12.11", - "@babel/types": "^7.12.12", + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.12.13", + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/parser": "^7.12.13", + "@babel/types": "^7.12.13", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.19" - }, - "dependencies": { - "@babel/helper-function-name": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", - "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.12.10", - "@babel/template": "^7.12.7", - "@babel/types": "^7.12.11" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", - "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", - "dev": true, - "requires": { - "@babel/types": "^7.12.11" - } - } } }, "@babel/types": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", - "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.13.tgz", + "integrity": "sha512-oKrdZTld2im1z8bDwTOQvUbxKwE+854zc16qWZQlcTqMN00pWxHQ4ZeOq0yDMnisOpRykH2/5Qqcrk/OlbAjiQ==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", @@ -1225,33 +1669,22 @@ } }, "@babel/helper-create-regexp-features-plugin": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.7.tgz", - "integrity": "sha512-idnutvQPdpbduutvi3JVfEgcVIHooQnhvhx0Nk9isOINOIGYkZea1Pk2JlJRiUnMefrlvr0vkByATBY/mB4vjQ==", + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.16.tgz", + "integrity": "sha512-jAcQ1biDYZBdaAxB4yg46/XirgX7jBDiMHDbwYQOgtViLBXGxJpZQ24jutmBqAIB/q+AwB6j+NbBXjKxEY8vqg==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.10.4", + "@babel/helper-annotate-as-pure": "^7.12.13", "regexpu-core": "^4.7.1" } }, - "@babel/helper-define-map": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.10.5.tgz", - "integrity": "sha512-fMw4kgFB720aQFXSVaXr79pjjcW5puTCM16+rECJ/plGS+zByelE8l9nCpV1GibxTnFVmUuYG9U8wYfQHdzOEQ==", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.10.4", - "@babel/types": "^7.10.5", - "lodash": "^4.17.19" - } - }, "@babel/helper-explode-assignable-expression": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.12.1.tgz", - "integrity": "sha512-dmUwH8XmlrUpVqgtZ737tK88v07l840z9j3OEhCLwKTkjlvKpfqXVIZ0wpK3aeOxspwGrf/5AP5qLx4rO3w5rA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.12.13.tgz", + "integrity": "sha512-5loeRNvMo9mx1dA/d6yNi+YiKziJZFylZnCo1nmFF4qPU4yJ14abhWESuSMQSlQxWdxdOFzxXjk/PpfudTtYyw==", "dev": true, "requires": { - "@babel/types": "^7.12.1" + "@babel/types": "^7.12.13" }, "dependencies": { "@babel/helper-validator-identifier": { @@ -1261,9 +1694,9 @@ "dev": true }, "@babel/types": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", - "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.13.tgz", + "integrity": "sha512-oKrdZTld2im1z8bDwTOQvUbxKwE+854zc16qWZQlcTqMN00pWxHQ4ZeOq0yDMnisOpRykH2/5Qqcrk/OlbAjiQ==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", @@ -1327,12 +1760,31 @@ } }, "@babel/helper-hoist-variables": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.4.tgz", - "integrity": "sha512-wljroF5PgCk2juF69kanHVs6vrLwIPNp6DLD+Lrl3hoQ3PpPPikaDRNFA+0t81NOoMt2DL6WW/mdU8k4k6ZzuA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.12.13.tgz", + "integrity": "sha512-KSC5XSj5HreRhYQtZ3cnSnQwDzgnbdUDEFsxkN0m6Q3WrCRt72xrnZ8+h+pX7YxM7hr87zIO3a/v5p/H3TrnVw==", "dev": true, "requires": { - "@babel/types": "^7.10.4" + "@babel/types": "^7.12.13" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + }, + "@babel/types": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.13.tgz", + "integrity": "sha512-oKrdZTld2im1z8bDwTOQvUbxKwE+854zc16qWZQlcTqMN00pWxHQ4ZeOq0yDMnisOpRykH2/5Qqcrk/OlbAjiQ==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.12.11", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-member-expression-to-functions": { @@ -1411,20 +1863,20 @@ } }, "@babel/helper-plugin-utils": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", - "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.12.13.tgz", + "integrity": "sha512-C+10MXCXJLiR6IeG9+Wiejt9jmtFpxUc3MQqCmPY8hfCjyUGl9kT+B2okzEZrtykiwrc4dbCPdDoz0A/HQbDaA==", "dev": true }, "@babel/helper-remap-async-to-generator": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.12.1.tgz", - "integrity": "sha512-9d0KQCRM8clMPcDwo8SevNs+/9a8yWVVmaE80FGJcEP8N1qToREmWEGnBn8BUlJhYRFz6fqxeRL1sl5Ogsed7A==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.12.13.tgz", + "integrity": "sha512-Qa6PU9vNcj1NZacZZI1Mvwt+gXDH6CTfgAkSjeRMLE8HxtDK76+YDId6NQR+z7Rgd5arhD2cIbS74r0SxD6PDA==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.10.4", - "@babel/helper-wrap-function": "^7.10.4", - "@babel/types": "^7.12.1" + "@babel/helper-annotate-as-pure": "^7.12.13", + "@babel/helper-wrap-function": "^7.12.13", + "@babel/types": "^7.12.13" }, "dependencies": { "@babel/helper-validator-identifier": { @@ -1434,9 +1886,9 @@ "dev": true }, "@babel/types": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", - "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.13.tgz", + "integrity": "sha512-oKrdZTld2im1z8bDwTOQvUbxKwE+854zc16qWZQlcTqMN00pWxHQ4ZeOq0yDMnisOpRykH2/5Qqcrk/OlbAjiQ==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", @@ -1517,9 +1969,9 @@ "dev": true }, "@babel/types": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", - "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.13.tgz", + "integrity": "sha512-oKrdZTld2im1z8bDwTOQvUbxKwE+854zc16qWZQlcTqMN00pWxHQ4ZeOq0yDMnisOpRykH2/5Qqcrk/OlbAjiQ==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", @@ -1545,78 +1997,148 @@ "dev": true }, "@babel/helper-validator-option": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.11.tgz", - "integrity": "sha512-TBFCyj939mFSdeX7U7DDj32WtzYY7fDcalgq8v3fBZMNOJQNn7nOYzMaUCiPxPYfCup69mtIpqlKgMZLvQ8Xhw==", + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.16.tgz", + "integrity": "sha512-uCgsDBPUQDvzr11ePPo4TVEocxj8RXjUVSC/Y8N1YpVAI/XDdUwGJu78xmlGhTxj2ntaWM7n9LQdRtyhOzT2YQ==", "dev": true }, "@babel/helper-wrap-function": { - "version": "7.12.3", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.12.3.tgz", - "integrity": "sha512-Cvb8IuJDln3rs6tzjW3Y8UeelAOdnpB8xtQ4sme2MSZ9wOxrbThporC0y/EtE16VAtoyEfLM404Xr1e0OOp+ow==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.12.13.tgz", + "integrity": "sha512-t0aZFEmBJ1LojdtJnhOaQEVejnzYhyjWHSsNSNo8vOYRbAJNh6r6GQF7pd36SqG7OKGbn+AewVQ/0IfYfIuGdw==", "dev": true, "requires": { - "@babel/helper-function-name": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/helper-function-name": "^7.12.13", + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.12.13", + "@babel/types": "^7.12.13" }, "dependencies": { "@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", + "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", "dev": true, "requires": { - "@babel/highlight": "^7.10.4" + "@babel/highlight": "^7.12.13" } }, - "@babel/highlight": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", - "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "@babel/generator": { + "version": "7.12.15", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.15.tgz", + "integrity": "sha512-6F2xHxBiFXWNSGb7vyCUTBF8RCLY66rS0zEPcP8t/nQyXjha5EuK4z7H5o7fWG8B4M7y6mqVWq1J+1PuwRhecQ==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/types": "^7.12.13", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz", + "integrity": "sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.12.13", + "@babel/template": "^7.12.13", + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", + "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", + "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + }, + "@babel/highlight": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.12.13.tgz", + "integrity": "sha512-kocDQvIbgMKlWxXe9fof3TQ+gkIPOUSEYhJjqUjvKMez3krV7vbzYCDq39Oj11UAVK7JqPVGQPlgE85dPNlQww==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.12.11", "chalk": "^2.0.0", "js-tokens": "^4.0.0" } }, "@babel/parser": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", - "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.16.tgz", + "integrity": "sha512-c/+u9cqV6F0+4Hpq01jnJO+GLp2DdT63ppz9Xa+6cHaajM9VFzK/iDXiKK65YtpeVwu+ctfS6iqlMqRgQRzeCw==", "dev": true }, "@babel/template": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", - "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", + "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", "dev": true, "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/parser": "^7.12.7", - "@babel/types": "^7.12.7" - }, - "dependencies": { - "@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", - "dev": true - }, - "@babel/types": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", - "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.12.11", - "lodash": "^4.17.19", - "to-fast-properties": "^2.0.0" - } - } + "@babel/code-frame": "^7.12.13", + "@babel/parser": "^7.12.13", + "@babel/types": "^7.12.13" } + }, + "@babel/traverse": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.13.tgz", + "integrity": "sha512-3Zb4w7eE/OslI0fTp8c7b286/cQps3+vdLW3UcwC8VSJC6GbKn55aeVVu2QJNuCDoeKyptLOFrPq8WqZZBodyA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.12.13", + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/parser": "^7.12.13", + "@babel/types": "^7.12.13", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.19" + } + }, + "@babel/types": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.13.tgz", + "integrity": "sha512-oKrdZTld2im1z8bDwTOQvUbxKwE+854zc16qWZQlcTqMN00pWxHQ4ZeOq0yDMnisOpRykH2/5Qqcrk/OlbAjiQ==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.12.11", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true } } }, @@ -1682,136 +2204,136 @@ "dev": true }, "@babel/plugin-proposal-async-generator-functions": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.12.12.tgz", - "integrity": "sha512-nrz9y0a4xmUrRq51bYkWJIO5SBZyG2ys2qinHsN0zHDHVsUaModrkpyWWWXfGqYQmOL3x9sQIcTNN/pBGpo09A==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.12.13.tgz", + "integrity": "sha512-1KH46Hx4WqP77f978+5Ye/VUbuwQld2hph70yaw2hXS2v7ER2f3nlpNMu909HO2rbvP0NKLlMVDPh9KXklVMhA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-remap-async-to-generator": "^7.12.1", + "@babel/helper-plugin-utils": "^7.12.13", + "@babel/helper-remap-async-to-generator": "^7.12.13", "@babel/plugin-syntax-async-generators": "^7.8.0" } }, "@babel/plugin-proposal-class-properties": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.12.1.tgz", - "integrity": "sha512-cKp3dlQsFsEs5CWKnN7BnSHOd0EOW8EKpEjkoz1pO2E5KzIDNV9Ros1b0CnmbVgAGXJubOYVBOGCT1OmJwOI7w==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.12.13.tgz", + "integrity": "sha512-8SCJ0Ddrpwv4T7Gwb33EmW1V9PY5lggTO+A8WjyIwxrSHDUyBw4MtF96ifn1n8H806YlxbVCoKXbbmzD6RD+cA==", "dev": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-create-class-features-plugin": "^7.12.13", + "@babel/helper-plugin-utils": "^7.12.13" } }, "@babel/plugin-proposal-dynamic-import": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.12.1.tgz", - "integrity": "sha512-a4rhUSZFuq5W8/OO8H7BL5zspjnc1FLd9hlOxIK/f7qG4a0qsqk8uvF/ywgBA8/OmjsapjpvaEOYItfGG1qIvQ==", + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.12.16.tgz", + "integrity": "sha512-yiDkYFapVxNOCcBfLnsb/qdsliroM+vc3LHiZwS4gh7pFjo5Xq3BDhYBNn3H3ao+hWPvqeeTdU+s+FIvokov+w==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-plugin-utils": "^7.12.13", "@babel/plugin-syntax-dynamic-import": "^7.8.0" } }, "@babel/plugin-proposal-export-namespace-from": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.12.1.tgz", - "integrity": "sha512-6CThGf0irEkzujYS5LQcjBx8j/4aQGiVv7J9+2f7pGfxqyKh3WnmVJYW3hdrQjyksErMGBPQrCnHfOtna+WLbw==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.12.13.tgz", + "integrity": "sha512-INAgtFo4OnLN3Y/j0VwAgw3HDXcDtX+C/erMvWzuV9v71r7urb6iyMXu7eM9IgLr1ElLlOkaHjJ0SbCmdOQ3Iw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-plugin-utils": "^7.12.13", "@babel/plugin-syntax-export-namespace-from": "^7.8.3" } }, "@babel/plugin-proposal-json-strings": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.12.1.tgz", - "integrity": "sha512-GoLDUi6U9ZLzlSda2Df++VSqDJg3CG+dR0+iWsv6XRw1rEq+zwt4DirM9yrxW6XWaTpmai1cWJLMfM8qQJf+yw==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.12.13.tgz", + "integrity": "sha512-v9eEi4GiORDg8x+Dmi5r8ibOe0VXoKDeNPYcTTxdGN4eOWikrJfDJCJrr1l5gKGvsNyGJbrfMftC2dTL6oz7pg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-plugin-utils": "^7.12.13", "@babel/plugin-syntax-json-strings": "^7.8.0" } }, "@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.12.1.tgz", - "integrity": "sha512-k8ZmVv0JU+4gcUGeCDZOGd0lCIamU/sMtIiX3UWnUc5yzgq6YUGyEolNYD+MLYKfSzgECPcqetVcJP9Afe/aCA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.12.13.tgz", + "integrity": "sha512-fqmiD3Lz7jVdK6kabeSr1PZlWSUVqSitmHEe3Z00dtGTKieWnX9beafvavc32kjORa5Bai4QNHgFDwWJP+WtSQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-plugin-utils": "^7.12.13", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" } }, "@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.12.1.tgz", - "integrity": "sha512-nZY0ESiaQDI1y96+jk6VxMOaL4LPo/QDHBqL+SF3/vl6dHkTwHlOI8L4ZwuRBHgakRBw5zsVylel7QPbbGuYgg==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.12.13.tgz", + "integrity": "sha512-Qoxpy+OxhDBI5kRqliJFAl4uWXk3Bn24WeFstPH0iLymFehSAUR8MHpqU7njyXv/qbo7oN6yTy5bfCmXdKpo1Q==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-plugin-utils": "^7.12.13", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0" } }, "@babel/plugin-proposal-numeric-separator": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.7.tgz", - "integrity": "sha512-8c+uy0qmnRTeukiGsjLGy6uVs/TFjJchGXUeBqlG4VWYOdJWkhhVPdQ3uHwbmalfJwv2JsV0qffXP4asRfL2SQ==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.13.tgz", + "integrity": "sha512-O1jFia9R8BUCl3ZGB7eitaAPu62TXJRHn7rh+ojNERCFyqRwJMTmhz+tJ+k0CwI6CLjX/ee4qW74FSqlq9I35w==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-plugin-utils": "^7.12.13", "@babel/plugin-syntax-numeric-separator": "^7.10.4" } }, "@babel/plugin-proposal-object-rest-spread": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.1.tgz", - "integrity": "sha512-s6SowJIjzlhx8o7lsFx5zmY4At6CTtDvgNQDdPzkBQucle58A6b/TTeEBYtyDgmcXjUTM+vE8YOGHZzzbc/ioA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.13.tgz", + "integrity": "sha512-WvA1okB/0OS/N3Ldb3sziSrXg6sRphsBgqiccfcQq7woEn5wQLNX82Oc4PlaFcdwcWHuQXAtb8ftbS8Fbsg/sg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-plugin-utils": "^7.12.13", "@babel/plugin-syntax-object-rest-spread": "^7.8.0", - "@babel/plugin-transform-parameters": "^7.12.1" + "@babel/plugin-transform-parameters": "^7.12.13" } }, "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.12.1.tgz", - "integrity": "sha512-hFvIjgprh9mMw5v42sJWLI1lzU5L2sznP805zeT6rySVRA0Y18StRhDqhSxlap0oVgItRsB6WSROp4YnJTJz0g==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.12.13.tgz", + "integrity": "sha512-9+MIm6msl9sHWg58NvqpNpLtuFbmpFYk37x8kgnGzAHvX35E1FyAwSUt5hIkSoWJFSAH+iwU8bJ4fcD1zKXOzg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-plugin-utils": "^7.12.13", "@babel/plugin-syntax-optional-catch-binding": "^7.8.0" } }, "@babel/plugin-proposal-optional-chaining": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.12.7.tgz", - "integrity": "sha512-4ovylXZ0PWmwoOvhU2vhnzVNnm88/Sm9nx7V8BPgMvAzn5zDou3/Awy0EjglyubVHasJj+XCEkr/r1X3P5elCA==", + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.12.16.tgz", + "integrity": "sha512-O3ohPwOhkwji5Mckb7F/PJpJVJY3DpPsrt/F0Bk40+QMk9QpAIqeGusHWqu/mYqsM8oBa6TziL/2mbERWsUZjg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-plugin-utils": "^7.12.13", "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1", "@babel/plugin-syntax-optional-chaining": "^7.8.0" } }, "@babel/plugin-proposal-private-methods": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.12.1.tgz", - "integrity": "sha512-mwZ1phvH7/NHK6Kf8LP7MYDogGV+DKB1mryFOEwx5EBNQrosvIczzZFTUmWaeujd5xT6G1ELYWUz3CutMhjE1w==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.12.13.tgz", + "integrity": "sha512-sV0V57uUwpauixvR7s2o75LmwJI6JECwm5oPUY5beZB1nBl2i37hc7CJGqB5G+58fur5Y6ugvl3LRONk5x34rg==", "dev": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-create-class-features-plugin": "^7.12.13", + "@babel/helper-plugin-utils": "^7.12.13" } }, "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.1.tgz", - "integrity": "sha512-MYq+l+PvHuw/rKUz1at/vb6nCnQ2gmJBNaM62z0OgH7B2W1D9pvkpYtlti9bGtizNIU1K3zm4bZF9F91efVY0w==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.13.tgz", + "integrity": "sha512-XyJmZidNfofEkqFV5VC/bLabGmO5QzenPO/YOfGuEbgU+2sSwMmio3YLb4WtBgcmmdwZHyVyv8on77IUjQ5Gvg==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-create-regexp-features-plugin": "^7.12.13", + "@babel/helper-plugin-utils": "^7.12.13" } }, "@babel/plugin-syntax-async-generators": { @@ -1824,12 +2346,12 @@ } }, "@babel/plugin-syntax-class-properties": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.1.tgz", - "integrity": "sha512-U40A76x5gTwmESz+qiqssqmeEsKvcSyvtgktrm0uzcARAmM9I1jR221f6Oq+GmHrcD+LvZDag1UTOTe2fL3TeA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" } }, "@babel/plugin-syntax-dynamic-import": { @@ -1914,21 +2436,21 @@ } }, "@babel/plugin-syntax-top-level-await": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.1.tgz", - "integrity": "sha512-i7ooMZFS+a/Om0crxZodrTzNEPJHZrlMVGMTEpFAj6rYY/bKCddB0Dk/YxfPuYXOopuhKk/e1jV6h+WUU9XN3A==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.13.tgz", + "integrity": "sha512-A81F9pDwyS7yM//KwbCSDqy3Uj4NMIurtplxphWxoYtNPov7cJsDkAFNNyVlIZ3jwGycVsurZ+LtOA8gZ376iQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" } }, "@babel/plugin-transform-arrow-functions": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.12.1.tgz", - "integrity": "sha512-5QB50qyN44fzzz4/qxDPQMBCTHgxg3n0xRBLJUmBlLoU/sFvxVWGZF/ZUfMVDQuJUKXaBhbupxIzIfZ6Fwk/0A==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.12.13.tgz", + "integrity": "sha512-tBtuN6qtCTd+iHzVZVOMNp+L04iIJBpqkdY42tWbmjIT5wvR2kx7gxMBsyhQtFzHwBbyGi9h8J8r9HgnOpQHxg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" } }, "@babel/plugin-transform-async-to-generator": { @@ -1943,12 +2465,12 @@ }, "dependencies": { "@babel/helper-module-imports": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz", - "integrity": "sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.13.tgz", + "integrity": "sha512-NGmfvRp9Rqxy0uHSSVP+SRIW1q31a7Ji10cLBcqSDUngGentY4FRiHOFZFE1CLU5eiL0oE8reH7Tg1y99TDM/g==", "dev": true, "requires": { - "@babel/types": "^7.12.5" + "@babel/types": "^7.12.13" } }, "@babel/helper-validator-identifier": { @@ -1958,9 +2480,9 @@ "dev": true }, "@babel/types": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", - "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.13.tgz", + "integrity": "sha512-oKrdZTld2im1z8bDwTOQvUbxKwE+854zc16qWZQlcTqMN00pWxHQ4ZeOq0yDMnisOpRykH2/5Qqcrk/OlbAjiQ==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", @@ -1971,98 +2493,115 @@ } }, "@babel/plugin-transform-block-scoped-functions": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.1.tgz", - "integrity": "sha512-5OpxfuYnSgPalRpo8EWGPzIYf0lHBWORCkj5M0oLBwHdlux9Ri36QqGW3/LR13RSVOAoUUMzoPI/jpE4ABcHoA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.13.tgz", + "integrity": "sha512-zNyFqbc3kI/fVpqwfqkg6RvBgFpC4J18aKKMmv7KdQ/1GgREapSJAykLMVNwfRGO3BtHj3YQZl8kxCXPcVMVeg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" } }, "@babel/plugin-transform-block-scoping": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.12.tgz", - "integrity": "sha512-VOEPQ/ExOVqbukuP7BYJtI5ZxxsmegTwzZ04j1aF0dkSypGo9XpDHuOrABsJu+ie+penpSJheDJ11x1BEZNiyQ==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.13.tgz", + "integrity": "sha512-Pxwe0iqWJX4fOOM2kEZeUuAxHMWb9nK+9oh5d11bsLoB0xMg+mkDpt0eYuDZB7ETrY9bbcVlKUGTOGWy7BHsMQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" } }, "@babel/plugin-transform-classes": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.12.1.tgz", - "integrity": "sha512-/74xkA7bVdzQTBeSUhLLJgYIcxw/dpEpCdRDiHgPJ3Mv6uC11UhjpOhl72CgqbBCmt1qtssCyB2xnJm1+PFjog==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.12.13.tgz", + "integrity": "sha512-cqZlMlhCC1rVnxE5ZGMtIb896ijL90xppMiuWXcwcOAuFczynpd3KYemb91XFFPi3wJSe/OcrX9lXoowatkkxA==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.10.4", - "@babel/helper-define-map": "^7.10.4", - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-optimise-call-expression": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-replace-supers": "^7.12.1", - "@babel/helper-split-export-declaration": "^7.10.4", + "@babel/helper-annotate-as-pure": "^7.12.13", + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-optimise-call-expression": "^7.12.13", + "@babel/helper-plugin-utils": "^7.12.13", + "@babel/helper-replace-supers": "^7.12.13", + "@babel/helper-split-export-declaration": "^7.12.13", "globals": "^11.1.0" }, "dependencies": { "@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", + "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", "dev": true, "requires": { - "@babel/highlight": "^7.10.4" + "@babel/highlight": "^7.12.13" } }, "@babel/generator": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", - "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", + "version": "7.12.15", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.15.tgz", + "integrity": "sha512-6F2xHxBiFXWNSGb7vyCUTBF8RCLY66rS0zEPcP8t/nQyXjha5EuK4z7H5o7fWG8B4M7y6mqVWq1J+1PuwRhecQ==", "dev": true, "requires": { - "@babel/types": "^7.12.11", + "@babel/types": "^7.12.13", "jsesc": "^2.5.1", "source-map": "^0.5.0" } }, - "@babel/helper-get-function-arity": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", - "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", + "@babel/helper-function-name": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz", + "integrity": "sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==", "dev": true, "requires": { - "@babel/types": "^7.12.10" + "@babel/helper-get-function-arity": "^7.12.13", + "@babel/template": "^7.12.13", + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", + "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13" } }, "@babel/helper-member-expression-to-functions": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", - "integrity": "sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw==", + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.16.tgz", + "integrity": "sha512-zYoZC1uvebBFmj1wFAlXwt35JLEgecefATtKp20xalwEK8vHAixLBXTGxNrVGEmTT+gzOThUgr8UEdgtalc1BQ==", "dev": true, "requires": { - "@babel/types": "^7.12.7" + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz", + "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13" } }, "@babel/helper-replace-supers": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz", - "integrity": "sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.13.tgz", + "integrity": "sha512-pctAOIAMVStI2TMLhozPKbf5yTEXc0OJa0eENheb4w09SrgOWEs+P4nTOZYJQCqs8JlErGLDPDJTiGIp3ygbLg==", "dev": true, "requires": { - "@babel/helper-member-expression-to-functions": "^7.12.7", - "@babel/helper-optimise-call-expression": "^7.12.10", - "@babel/traverse": "^7.12.10", - "@babel/types": "^7.12.11" - }, - "dependencies": { - "@babel/helper-optimise-call-expression": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz", - "integrity": "sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ==", - "dev": true, - "requires": { - "@babel/types": "^7.12.10" - } - } + "@babel/helper-member-expression-to-functions": "^7.12.13", + "@babel/helper-optimise-call-expression": "^7.12.13", + "@babel/traverse": "^7.12.13", + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", + "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13" } }, "@babel/helper-validator-identifier": { @@ -2072,76 +2611,54 @@ "dev": true }, "@babel/highlight": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", - "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.12.13.tgz", + "integrity": "sha512-kocDQvIbgMKlWxXe9fof3TQ+gkIPOUSEYhJjqUjvKMez3krV7vbzYCDq39Oj11UAVK7JqPVGQPlgE85dPNlQww==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/helper-validator-identifier": "^7.12.11", "chalk": "^2.0.0", "js-tokens": "^4.0.0" } }, "@babel/parser": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", - "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.16.tgz", + "integrity": "sha512-c/+u9cqV6F0+4Hpq01jnJO+GLp2DdT63ppz9Xa+6cHaajM9VFzK/iDXiKK65YtpeVwu+ctfS6iqlMqRgQRzeCw==", "dev": true }, "@babel/template": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", - "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", + "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", "dev": true, "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/parser": "^7.12.7", - "@babel/types": "^7.12.7" + "@babel/code-frame": "^7.12.13", + "@babel/parser": "^7.12.13", + "@babel/types": "^7.12.13" } }, "@babel/traverse": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", - "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.13.tgz", + "integrity": "sha512-3Zb4w7eE/OslI0fTp8c7b286/cQps3+vdLW3UcwC8VSJC6GbKn55aeVVu2QJNuCDoeKyptLOFrPq8WqZZBodyA==", "dev": true, "requires": { - "@babel/code-frame": "^7.12.11", - "@babel/generator": "^7.12.11", - "@babel/helper-function-name": "^7.12.11", - "@babel/helper-split-export-declaration": "^7.12.11", - "@babel/parser": "^7.12.11", - "@babel/types": "^7.12.12", + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.12.13", + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/parser": "^7.12.13", + "@babel/types": "^7.12.13", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.19" - }, - "dependencies": { - "@babel/helper-function-name": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", - "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.12.10", - "@babel/template": "^7.12.7", - "@babel/types": "^7.12.11" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", - "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", - "dev": true, - "requires": { - "@babel/types": "^7.12.11" - } - } } }, "@babel/types": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", - "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.13.tgz", + "integrity": "sha512-oKrdZTld2im1z8bDwTOQvUbxKwE+854zc16qWZQlcTqMN00pWxHQ4ZeOq0yDMnisOpRykH2/5Qqcrk/OlbAjiQ==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", @@ -2167,276 +2684,350 @@ } }, "@babel/plugin-transform-computed-properties": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.12.1.tgz", - "integrity": "sha512-vVUOYpPWB7BkgUWPo4C44mUQHpTZXakEqFjbv8rQMg7TC6S6ZhGZ3otQcRH6u7+adSlE5i0sp63eMC/XGffrzg==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.12.13.tgz", + "integrity": "sha512-dDfuROUPGK1mTtLKyDPUavmj2b6kFu82SmgpztBFEO974KMjJT+Ytj3/oWsTUMBmgPcp9J5Pc1SlcAYRpJ2hRA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" } }, "@babel/plugin-transform-destructuring": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.12.1.tgz", - "integrity": "sha512-fRMYFKuzi/rSiYb2uRLiUENJOKq4Gnl+6qOv5f8z0TZXg3llUwUhsNNwrwaT/6dUhJTzNpBr+CUvEWBtfNY1cw==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.12.13.tgz", + "integrity": "sha512-Dn83KykIFzjhA3FDPA1z4N+yfF3btDGhjnJwxIj0T43tP0flCujnU8fKgEkf0C1biIpSv9NZegPBQ1J6jYkwvQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" } }, "@babel/plugin-transform-dotall-regex": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.1.tgz", - "integrity": "sha512-B2pXeRKoLszfEW7J4Hg9LoFaWEbr/kzo3teWHmtFCszjRNa/b40f9mfeqZsIDLLt/FjwQ6pz/Gdlwy85xNckBA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.13.tgz", + "integrity": "sha512-foDrozE65ZFdUC2OfgeOCrEPTxdB3yjqxpXh8CH+ipd9CHd4s/iq81kcUpyH8ACGNEPdFqbtzfgzbT/ZGlbDeQ==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-create-regexp-features-plugin": "^7.12.13", + "@babel/helper-plugin-utils": "^7.12.13" } }, "@babel/plugin-transform-duplicate-keys": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.1.tgz", - "integrity": "sha512-iRght0T0HztAb/CazveUpUQrZY+aGKKaWXMJ4uf9YJtqxSUe09j3wteztCUDRHs+SRAL7yMuFqUsLoAKKzgXjw==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.13.tgz", + "integrity": "sha512-NfADJiiHdhLBW3pulJlJI2NB0t4cci4WTZ8FtdIuNc2+8pslXdPtRRAEWqUY+m9kNOk2eRYbTAOipAxlrOcwwQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" } }, "@babel/plugin-transform-exponentiation-operator": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.1.tgz", - "integrity": "sha512-7tqwy2bv48q+c1EHbXK0Zx3KXd2RVQp6OC7PbwFNt/dPTAV3Lu5sWtWuAj8owr5wqtWnqHfl2/mJlUmqkChKug==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.13.tgz", + "integrity": "sha512-fbUelkM1apvqez/yYx1/oICVnGo2KM5s63mhGylrmXUxK/IAXSIf87QIxVfZldWf4QsOafY6vV3bX8aMHSvNrA==", "dev": true, "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.12.13", + "@babel/helper-plugin-utils": "^7.12.13" } }, "@babel/plugin-transform-for-of": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.12.1.tgz", - "integrity": "sha512-Zaeq10naAsuHo7heQvyV0ptj4dlZJwZgNAtBYBnu5nNKJoW62m0zKcIEyVECrUKErkUkg6ajMy4ZfnVZciSBhg==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.12.13.tgz", + "integrity": "sha512-xCbdgSzXYmHGyVX3+BsQjcd4hv4vA/FDy7Kc8eOpzKmBBPEOTurt0w5fCRQaGl+GSBORKgJdstQ1rHl4jbNseQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" } }, "@babel/plugin-transform-function-name": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.1.tgz", - "integrity": "sha512-JF3UgJUILoFrFMEnOJLJkRHSk6LUSXLmEFsA23aR2O5CSLUxbeUX1IZ1YQ7Sn0aXb601Ncwjx73a+FVqgcljVw==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.13.tgz", + "integrity": "sha512-6K7gZycG0cmIwwF7uMK/ZqeCikCGVBdyP2J5SKNCXO5EOHcqi+z7Jwf8AmyDNcBgxET8DrEtCt/mPKPyAzXyqQ==", "dev": true, "requires": { - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-transform-literals": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.1.tgz", - "integrity": "sha512-+PxVGA+2Ag6uGgL0A5f+9rklOnnMccwEBzwYFL3EUaKuiyVnUipyXncFcfjSkbimLrODoqki1U9XxZzTvfN7IQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-transform-member-expression-literals": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.1.tgz", - "integrity": "sha512-1sxePl6z9ad0gFMB9KqmYofk34flq62aqMt9NqliS/7hPEpURUCMbyHXrMPlo282iY7nAvUB1aQd5mg79UD9Jg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-transform-modules-amd": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.12.1.tgz", - "integrity": "sha512-tDW8hMkzad5oDtzsB70HIQQRBiTKrhfgwC/KkJeGsaNFTdWhKNt/BiE8c5yj19XiGyrxpbkOfH87qkNg1YGlOQ==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4", - "babel-plugin-dynamic-import-node": "^2.3.3" + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-plugin-utils": "^7.12.13" }, "dependencies": { "@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", + "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", "dev": true, "requires": { - "@babel/highlight": "^7.10.4" - } - }, - "@babel/generator": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", - "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", - "dev": true, - "requires": { - "@babel/types": "^7.12.11", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" + "@babel/highlight": "^7.12.13" } }, "@babel/helper-function-name": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", - "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz", + "integrity": "sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.12.10", - "@babel/template": "^7.12.7", - "@babel/types": "^7.12.11" + "@babel/helper-get-function-arity": "^7.12.13", + "@babel/template": "^7.12.13", + "@babel/types": "^7.12.13" } }, "@babel/helper-get-function-arity": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", - "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", + "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", "dev": true, "requires": { - "@babel/types": "^7.12.10" + "@babel/types": "^7.12.13" } }, - "@babel/helper-member-expression-to-functions": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", - "integrity": "sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw==", - "dev": true, - "requires": { - "@babel/types": "^7.12.7" - } - }, - "@babel/helper-module-imports": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz", - "integrity": "sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==", - "dev": true, - "requires": { - "@babel/types": "^7.12.5" - } - }, - "@babel/helper-module-transforms": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz", - "integrity": "sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.12.1", - "@babel/helper-replace-supers": "^7.12.1", - "@babel/helper-simple-access": "^7.12.1", - "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/helper-validator-identifier": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.12.1", - "@babel/types": "^7.12.1", - "lodash": "^4.17.19" - } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz", - "integrity": "sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ==", - "dev": true, - "requires": { - "@babel/types": "^7.12.10" - } - }, - "@babel/helper-replace-supers": { + "@babel/helper-validator-identifier": { "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz", - "integrity": "sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA==", - "dev": true, - "requires": { - "@babel/helper-member-expression-to-functions": "^7.12.7", - "@babel/helper-optimise-call-expression": "^7.12.10", - "@babel/traverse": "^7.12.10", - "@babel/types": "^7.12.11" - } - }, - "@babel/helper-simple-access": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.1.tgz", - "integrity": "sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA==", - "dev": true, - "requires": { - "@babel/types": "^7.12.1" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", - "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", - "dev": true, - "requires": { - "@babel/types": "^7.12.11" - } + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true }, "@babel/highlight": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", - "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.12.13.tgz", + "integrity": "sha512-kocDQvIbgMKlWxXe9fof3TQ+gkIPOUSEYhJjqUjvKMez3krV7vbzYCDq39Oj11UAVK7JqPVGQPlgE85dPNlQww==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/helper-validator-identifier": "^7.12.11", "chalk": "^2.0.0", "js-tokens": "^4.0.0" } }, "@babel/parser": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", - "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.16.tgz", + "integrity": "sha512-c/+u9cqV6F0+4Hpq01jnJO+GLp2DdT63ppz9Xa+6cHaajM9VFzK/iDXiKK65YtpeVwu+ctfS6iqlMqRgQRzeCw==", "dev": true }, "@babel/template": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", - "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", + "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", "dev": true, "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/parser": "^7.12.7", - "@babel/types": "^7.12.7" + "@babel/code-frame": "^7.12.13", + "@babel/parser": "^7.12.13", + "@babel/types": "^7.12.13" + } + }, + "@babel/types": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.13.tgz", + "integrity": "sha512-oKrdZTld2im1z8bDwTOQvUbxKwE+854zc16qWZQlcTqMN00pWxHQ4ZeOq0yDMnisOpRykH2/5Qqcrk/OlbAjiQ==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.12.11", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + } + } + }, + "@babel/plugin-transform-literals": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.13.tgz", + "integrity": "sha512-FW+WPjSR7hiUxMcKqyNjP05tQ2kmBCdpEpZHY1ARm96tGQCCBvXKnpjILtDplUnJ/eHZ0lALLM+d2lMFSpYJrQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-member-expression-literals": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.13.tgz", + "integrity": "sha512-kxLkOsg8yir4YeEPHLuO2tXP9R/gTjpuTOjshqSpELUN3ZAg2jfDnKUvzzJxObun38sw3wm4Uu69sX/zA7iRvg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-modules-amd": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.12.13.tgz", + "integrity": "sha512-JHLOU0o81m5UqG0Ulz/fPC68/v+UTuGTWaZBUwpEk1fYQ1D9LfKV6MPn4ttJKqRo5Lm460fkzjLTL4EHvCprvA==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.12.13", + "@babel/helper-plugin-utils": "^7.12.13", + "babel-plugin-dynamic-import-node": "^2.3.3" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", + "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.12.13" + } + }, + "@babel/generator": { + "version": "7.12.15", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.15.tgz", + "integrity": "sha512-6F2xHxBiFXWNSGb7vyCUTBF8RCLY66rS0zEPcP8t/nQyXjha5EuK4z7H5o7fWG8B4M7y6mqVWq1J+1PuwRhecQ==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz", + "integrity": "sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.12.13", + "@babel/template": "^7.12.13", + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", + "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.16.tgz", + "integrity": "sha512-zYoZC1uvebBFmj1wFAlXwt35JLEgecefATtKp20xalwEK8vHAixLBXTGxNrVGEmTT+gzOThUgr8UEdgtalc1BQ==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-module-imports": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.13.tgz", + "integrity": "sha512-NGmfvRp9Rqxy0uHSSVP+SRIW1q31a7Ji10cLBcqSDUngGentY4FRiHOFZFE1CLU5eiL0oE8reH7Tg1y99TDM/g==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-module-transforms": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.13.tgz", + "integrity": "sha512-acKF7EjqOR67ASIlDTupwkKM1eUisNAjaSduo5Cz+793ikfnpe7p4Q7B7EWU2PCoSTPWsQkR7hRUWEIZPiVLGA==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.12.13", + "@babel/helper-replace-supers": "^7.12.13", + "@babel/helper-simple-access": "^7.12.13", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/helper-validator-identifier": "^7.12.11", + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.12.13", + "@babel/types": "^7.12.13", + "lodash": "^4.17.19" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz", + "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-replace-supers": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.13.tgz", + "integrity": "sha512-pctAOIAMVStI2TMLhozPKbf5yTEXc0OJa0eENheb4w09SrgOWEs+P4nTOZYJQCqs8JlErGLDPDJTiGIp3ygbLg==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.12.13", + "@babel/helper-optimise-call-expression": "^7.12.13", + "@babel/traverse": "^7.12.13", + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-simple-access": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.13.tgz", + "integrity": "sha512-0ski5dyYIHEfwpWGx5GPWhH35j342JaflmCeQmsPWcrOQDtCN6C1zKAVRFVbK53lPW2c9TsuLLSUDf0tIGJ5hA==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", + "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + }, + "@babel/highlight": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.12.13.tgz", + "integrity": "sha512-kocDQvIbgMKlWxXe9fof3TQ+gkIPOUSEYhJjqUjvKMez3krV7vbzYCDq39Oj11UAVK7JqPVGQPlgE85dPNlQww==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.12.11", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.16.tgz", + "integrity": "sha512-c/+u9cqV6F0+4Hpq01jnJO+GLp2DdT63ppz9Xa+6cHaajM9VFzK/iDXiKK65YtpeVwu+ctfS6iqlMqRgQRzeCw==", + "dev": true + }, + "@babel/template": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", + "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@babel/parser": "^7.12.13", + "@babel/types": "^7.12.13" } }, "@babel/traverse": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", - "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.13.tgz", + "integrity": "sha512-3Zb4w7eE/OslI0fTp8c7b286/cQps3+vdLW3UcwC8VSJC6GbKn55aeVVu2QJNuCDoeKyptLOFrPq8WqZZBodyA==", "dev": true, "requires": { - "@babel/code-frame": "^7.12.11", - "@babel/generator": "^7.12.11", - "@babel/helper-function-name": "^7.12.11", - "@babel/helper-split-export-declaration": "^7.12.11", - "@babel/parser": "^7.12.11", - "@babel/types": "^7.12.12", + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.12.13", + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/parser": "^7.12.13", + "@babel/types": "^7.12.13", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.19" } }, "@babel/types": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", - "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.13.tgz", + "integrity": "sha512-oKrdZTld2im1z8bDwTOQvUbxKwE+854zc16qWZQlcTqMN00pWxHQ4ZeOq0yDMnisOpRykH2/5Qqcrk/OlbAjiQ==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", "to-fast-properties": "^2.0.0" - }, - "dependencies": { - "@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", - "dev": true - } } }, "debug": { @@ -2457,193 +3048,191 @@ } }, "@babel/plugin-transform-modules-commonjs": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.12.1.tgz", - "integrity": "sha512-dY789wq6l0uLY8py9c1B48V8mVL5gZh/+PQ5ZPrylPYsnAvnEMjqsUXkuoDVPeVK+0VyGar+D08107LzDQ6pag==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.12.13.tgz", + "integrity": "sha512-OGQoeVXVi1259HjuoDnsQMlMkT9UkZT9TpXAsqWplS/M0N1g3TJAn/ByOCeQu7mfjc5WpSsRU+jV1Hd89ts0kQ==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-simple-access": "^7.12.1", + "@babel/helper-module-transforms": "^7.12.13", + "@babel/helper-plugin-utils": "^7.12.13", + "@babel/helper-simple-access": "^7.12.13", "babel-plugin-dynamic-import-node": "^2.3.3" }, "dependencies": { "@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", + "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", "dev": true, "requires": { - "@babel/highlight": "^7.10.4" + "@babel/highlight": "^7.12.13" } }, "@babel/generator": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", - "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", + "version": "7.12.15", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.15.tgz", + "integrity": "sha512-6F2xHxBiFXWNSGb7vyCUTBF8RCLY66rS0zEPcP8t/nQyXjha5EuK4z7H5o7fWG8B4M7y6mqVWq1J+1PuwRhecQ==", "dev": true, "requires": { - "@babel/types": "^7.12.11", + "@babel/types": "^7.12.13", "jsesc": "^2.5.1", "source-map": "^0.5.0" } }, "@babel/helper-function-name": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", - "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz", + "integrity": "sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.12.10", - "@babel/template": "^7.12.7", - "@babel/types": "^7.12.11" + "@babel/helper-get-function-arity": "^7.12.13", + "@babel/template": "^7.12.13", + "@babel/types": "^7.12.13" } }, "@babel/helper-get-function-arity": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", - "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", + "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", "dev": true, "requires": { - "@babel/types": "^7.12.10" + "@babel/types": "^7.12.13" } }, "@babel/helper-member-expression-to-functions": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", - "integrity": "sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw==", + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.16.tgz", + "integrity": "sha512-zYoZC1uvebBFmj1wFAlXwt35JLEgecefATtKp20xalwEK8vHAixLBXTGxNrVGEmTT+gzOThUgr8UEdgtalc1BQ==", "dev": true, "requires": { - "@babel/types": "^7.12.7" + "@babel/types": "^7.12.13" } }, "@babel/helper-module-imports": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz", - "integrity": "sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.13.tgz", + "integrity": "sha512-NGmfvRp9Rqxy0uHSSVP+SRIW1q31a7Ji10cLBcqSDUngGentY4FRiHOFZFE1CLU5eiL0oE8reH7Tg1y99TDM/g==", "dev": true, "requires": { - "@babel/types": "^7.12.5" + "@babel/types": "^7.12.13" } }, "@babel/helper-module-transforms": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz", - "integrity": "sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.13.tgz", + "integrity": "sha512-acKF7EjqOR67ASIlDTupwkKM1eUisNAjaSduo5Cz+793ikfnpe7p4Q7B7EWU2PCoSTPWsQkR7hRUWEIZPiVLGA==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.12.1", - "@babel/helper-replace-supers": "^7.12.1", - "@babel/helper-simple-access": "^7.12.1", - "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/helper-validator-identifier": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.12.1", - "@babel/types": "^7.12.1", + "@babel/helper-module-imports": "^7.12.13", + "@babel/helper-replace-supers": "^7.12.13", + "@babel/helper-simple-access": "^7.12.13", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/helper-validator-identifier": "^7.12.11", + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.12.13", + "@babel/types": "^7.12.13", "lodash": "^4.17.19" } }, "@babel/helper-optimise-call-expression": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz", - "integrity": "sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz", + "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==", "dev": true, "requires": { - "@babel/types": "^7.12.10" + "@babel/types": "^7.12.13" } }, "@babel/helper-replace-supers": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz", - "integrity": "sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.13.tgz", + "integrity": "sha512-pctAOIAMVStI2TMLhozPKbf5yTEXc0OJa0eENheb4w09SrgOWEs+P4nTOZYJQCqs8JlErGLDPDJTiGIp3ygbLg==", "dev": true, "requires": { - "@babel/helper-member-expression-to-functions": "^7.12.7", - "@babel/helper-optimise-call-expression": "^7.12.10", - "@babel/traverse": "^7.12.10", - "@babel/types": "^7.12.11" + "@babel/helper-member-expression-to-functions": "^7.12.13", + "@babel/helper-optimise-call-expression": "^7.12.13", + "@babel/traverse": "^7.12.13", + "@babel/types": "^7.12.13" } }, "@babel/helper-simple-access": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.1.tgz", - "integrity": "sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.13.tgz", + "integrity": "sha512-0ski5dyYIHEfwpWGx5GPWhH35j342JaflmCeQmsPWcrOQDtCN6C1zKAVRFVbK53lPW2c9TsuLLSUDf0tIGJ5hA==", "dev": true, "requires": { - "@babel/types": "^7.12.1" + "@babel/types": "^7.12.13" } }, "@babel/helper-split-export-declaration": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", - "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", + "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", "dev": true, "requires": { - "@babel/types": "^7.12.11" + "@babel/types": "^7.12.13" } }, + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + }, "@babel/highlight": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", - "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.12.13.tgz", + "integrity": "sha512-kocDQvIbgMKlWxXe9fof3TQ+gkIPOUSEYhJjqUjvKMez3krV7vbzYCDq39Oj11UAVK7JqPVGQPlgE85dPNlQww==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/helper-validator-identifier": "^7.12.11", "chalk": "^2.0.0", "js-tokens": "^4.0.0" } }, "@babel/parser": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", - "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.16.tgz", + "integrity": "sha512-c/+u9cqV6F0+4Hpq01jnJO+GLp2DdT63ppz9Xa+6cHaajM9VFzK/iDXiKK65YtpeVwu+ctfS6iqlMqRgQRzeCw==", "dev": true }, "@babel/template": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", - "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", + "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", "dev": true, "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/parser": "^7.12.7", - "@babel/types": "^7.12.7" + "@babel/code-frame": "^7.12.13", + "@babel/parser": "^7.12.13", + "@babel/types": "^7.12.13" } }, "@babel/traverse": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", - "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.13.tgz", + "integrity": "sha512-3Zb4w7eE/OslI0fTp8c7b286/cQps3+vdLW3UcwC8VSJC6GbKn55aeVVu2QJNuCDoeKyptLOFrPq8WqZZBodyA==", "dev": true, "requires": { - "@babel/code-frame": "^7.12.11", - "@babel/generator": "^7.12.11", - "@babel/helper-function-name": "^7.12.11", - "@babel/helper-split-export-declaration": "^7.12.11", - "@babel/parser": "^7.12.11", - "@babel/types": "^7.12.12", + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.12.13", + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/parser": "^7.12.13", + "@babel/types": "^7.12.13", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.19" } }, "@babel/types": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", - "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.13.tgz", + "integrity": "sha512-oKrdZTld2im1z8bDwTOQvUbxKwE+854zc16qWZQlcTqMN00pWxHQ4ZeOq0yDMnisOpRykH2/5Qqcrk/OlbAjiQ==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", "to-fast-properties": "^2.0.0" - }, - "dependencies": { - "@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", - "dev": true - } } }, "debug": { @@ -2664,194 +3253,192 @@ } }, "@babel/plugin-transform-modules-systemjs": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.12.1.tgz", - "integrity": "sha512-Hn7cVvOavVh8yvW6fLwveFqSnd7rbQN3zJvoPNyNaQSvgfKmDBO9U1YL9+PCXGRlZD9tNdWTy5ACKqMuzyn32Q==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.12.13.tgz", + "integrity": "sha512-aHfVjhZ8QekaNF/5aNdStCGzwTbU7SI5hUybBKlMzqIMC7w7Ho8hx5a4R/DkTHfRfLwHGGxSpFt9BfxKCoXKoA==", "dev": true, "requires": { - "@babel/helper-hoist-variables": "^7.10.4", - "@babel/helper-module-transforms": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/helper-hoist-variables": "^7.12.13", + "@babel/helper-module-transforms": "^7.12.13", + "@babel/helper-plugin-utils": "^7.12.13", + "@babel/helper-validator-identifier": "^7.12.11", "babel-plugin-dynamic-import-node": "^2.3.3" }, "dependencies": { "@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", + "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", "dev": true, "requires": { - "@babel/highlight": "^7.10.4" + "@babel/highlight": "^7.12.13" } }, "@babel/generator": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", - "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", + "version": "7.12.15", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.15.tgz", + "integrity": "sha512-6F2xHxBiFXWNSGb7vyCUTBF8RCLY66rS0zEPcP8t/nQyXjha5EuK4z7H5o7fWG8B4M7y6mqVWq1J+1PuwRhecQ==", "dev": true, "requires": { - "@babel/types": "^7.12.11", + "@babel/types": "^7.12.13", "jsesc": "^2.5.1", "source-map": "^0.5.0" } }, "@babel/helper-function-name": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", - "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz", + "integrity": "sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.12.10", - "@babel/template": "^7.12.7", - "@babel/types": "^7.12.11" + "@babel/helper-get-function-arity": "^7.12.13", + "@babel/template": "^7.12.13", + "@babel/types": "^7.12.13" } }, "@babel/helper-get-function-arity": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", - "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", + "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", "dev": true, "requires": { - "@babel/types": "^7.12.10" + "@babel/types": "^7.12.13" } }, "@babel/helper-member-expression-to-functions": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", - "integrity": "sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw==", + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.16.tgz", + "integrity": "sha512-zYoZC1uvebBFmj1wFAlXwt35JLEgecefATtKp20xalwEK8vHAixLBXTGxNrVGEmTT+gzOThUgr8UEdgtalc1BQ==", "dev": true, "requires": { - "@babel/types": "^7.12.7" + "@babel/types": "^7.12.13" } }, "@babel/helper-module-imports": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz", - "integrity": "sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.13.tgz", + "integrity": "sha512-NGmfvRp9Rqxy0uHSSVP+SRIW1q31a7Ji10cLBcqSDUngGentY4FRiHOFZFE1CLU5eiL0oE8reH7Tg1y99TDM/g==", "dev": true, "requires": { - "@babel/types": "^7.12.5" + "@babel/types": "^7.12.13" } }, "@babel/helper-module-transforms": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz", - "integrity": "sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.13.tgz", + "integrity": "sha512-acKF7EjqOR67ASIlDTupwkKM1eUisNAjaSduo5Cz+793ikfnpe7p4Q7B7EWU2PCoSTPWsQkR7hRUWEIZPiVLGA==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.12.1", - "@babel/helper-replace-supers": "^7.12.1", - "@babel/helper-simple-access": "^7.12.1", - "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/helper-validator-identifier": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.12.1", - "@babel/types": "^7.12.1", + "@babel/helper-module-imports": "^7.12.13", + "@babel/helper-replace-supers": "^7.12.13", + "@babel/helper-simple-access": "^7.12.13", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/helper-validator-identifier": "^7.12.11", + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.12.13", + "@babel/types": "^7.12.13", "lodash": "^4.17.19" } }, "@babel/helper-optimise-call-expression": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz", - "integrity": "sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz", + "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==", "dev": true, "requires": { - "@babel/types": "^7.12.10" + "@babel/types": "^7.12.13" } }, "@babel/helper-replace-supers": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz", - "integrity": "sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.13.tgz", + "integrity": "sha512-pctAOIAMVStI2TMLhozPKbf5yTEXc0OJa0eENheb4w09SrgOWEs+P4nTOZYJQCqs8JlErGLDPDJTiGIp3ygbLg==", "dev": true, "requires": { - "@babel/helper-member-expression-to-functions": "^7.12.7", - "@babel/helper-optimise-call-expression": "^7.12.10", - "@babel/traverse": "^7.12.10", - "@babel/types": "^7.12.11" + "@babel/helper-member-expression-to-functions": "^7.12.13", + "@babel/helper-optimise-call-expression": "^7.12.13", + "@babel/traverse": "^7.12.13", + "@babel/types": "^7.12.13" } }, "@babel/helper-simple-access": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.1.tgz", - "integrity": "sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.13.tgz", + "integrity": "sha512-0ski5dyYIHEfwpWGx5GPWhH35j342JaflmCeQmsPWcrOQDtCN6C1zKAVRFVbK53lPW2c9TsuLLSUDf0tIGJ5hA==", "dev": true, "requires": { - "@babel/types": "^7.12.1" + "@babel/types": "^7.12.13" } }, "@babel/helper-split-export-declaration": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", - "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", + "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", "dev": true, "requires": { - "@babel/types": "^7.12.11" + "@babel/types": "^7.12.13" } }, + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + }, "@babel/highlight": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", - "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.12.13.tgz", + "integrity": "sha512-kocDQvIbgMKlWxXe9fof3TQ+gkIPOUSEYhJjqUjvKMez3krV7vbzYCDq39Oj11UAVK7JqPVGQPlgE85dPNlQww==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/helper-validator-identifier": "^7.12.11", "chalk": "^2.0.0", "js-tokens": "^4.0.0" } }, "@babel/parser": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", - "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.16.tgz", + "integrity": "sha512-c/+u9cqV6F0+4Hpq01jnJO+GLp2DdT63ppz9Xa+6cHaajM9VFzK/iDXiKK65YtpeVwu+ctfS6iqlMqRgQRzeCw==", "dev": true }, "@babel/template": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", - "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", + "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", "dev": true, "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/parser": "^7.12.7", - "@babel/types": "^7.12.7" + "@babel/code-frame": "^7.12.13", + "@babel/parser": "^7.12.13", + "@babel/types": "^7.12.13" } }, "@babel/traverse": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", - "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.13.tgz", + "integrity": "sha512-3Zb4w7eE/OslI0fTp8c7b286/cQps3+vdLW3UcwC8VSJC6GbKn55aeVVu2QJNuCDoeKyptLOFrPq8WqZZBodyA==", "dev": true, "requires": { - "@babel/code-frame": "^7.12.11", - "@babel/generator": "^7.12.11", - "@babel/helper-function-name": "^7.12.11", - "@babel/helper-split-export-declaration": "^7.12.11", - "@babel/parser": "^7.12.11", - "@babel/types": "^7.12.12", + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.12.13", + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/parser": "^7.12.13", + "@babel/types": "^7.12.13", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.19" } }, "@babel/types": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", - "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.13.tgz", + "integrity": "sha512-oKrdZTld2im1z8bDwTOQvUbxKwE+854zc16qWZQlcTqMN00pWxHQ4ZeOq0yDMnisOpRykH2/5Qqcrk/OlbAjiQ==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", "to-fast-properties": "^2.0.0" - }, - "dependencies": { - "@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", - "dev": true - } } }, "debug": { @@ -2872,191 +3459,189 @@ } }, "@babel/plugin-transform-modules-umd": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.12.1.tgz", - "integrity": "sha512-aEIubCS0KHKM0zUos5fIoQm+AZUMt1ZvMpqz0/H5qAQ7vWylr9+PLYurT+Ic7ID/bKLd4q8hDovaG3Zch2uz5Q==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.12.13.tgz", + "integrity": "sha512-BgZndyABRML4z6ibpi7Z98m4EVLFI9tVsZDADC14AElFaNHHBcJIovflJ6wtCqFxwy2YJ1tJhGRsr0yLPKoN+w==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-module-transforms": "^7.12.13", + "@babel/helper-plugin-utils": "^7.12.13" }, "dependencies": { "@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", + "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", "dev": true, "requires": { - "@babel/highlight": "^7.10.4" + "@babel/highlight": "^7.12.13" } }, "@babel/generator": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", - "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", + "version": "7.12.15", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.15.tgz", + "integrity": "sha512-6F2xHxBiFXWNSGb7vyCUTBF8RCLY66rS0zEPcP8t/nQyXjha5EuK4z7H5o7fWG8B4M7y6mqVWq1J+1PuwRhecQ==", "dev": true, "requires": { - "@babel/types": "^7.12.11", + "@babel/types": "^7.12.13", "jsesc": "^2.5.1", "source-map": "^0.5.0" } }, "@babel/helper-function-name": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", - "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz", + "integrity": "sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.12.10", - "@babel/template": "^7.12.7", - "@babel/types": "^7.12.11" + "@babel/helper-get-function-arity": "^7.12.13", + "@babel/template": "^7.12.13", + "@babel/types": "^7.12.13" } }, "@babel/helper-get-function-arity": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", - "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", + "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", "dev": true, "requires": { - "@babel/types": "^7.12.10" + "@babel/types": "^7.12.13" } }, "@babel/helper-member-expression-to-functions": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", - "integrity": "sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw==", + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.16.tgz", + "integrity": "sha512-zYoZC1uvebBFmj1wFAlXwt35JLEgecefATtKp20xalwEK8vHAixLBXTGxNrVGEmTT+gzOThUgr8UEdgtalc1BQ==", "dev": true, "requires": { - "@babel/types": "^7.12.7" + "@babel/types": "^7.12.13" } }, "@babel/helper-module-imports": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz", - "integrity": "sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.13.tgz", + "integrity": "sha512-NGmfvRp9Rqxy0uHSSVP+SRIW1q31a7Ji10cLBcqSDUngGentY4FRiHOFZFE1CLU5eiL0oE8reH7Tg1y99TDM/g==", "dev": true, "requires": { - "@babel/types": "^7.12.5" + "@babel/types": "^7.12.13" } }, "@babel/helper-module-transforms": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz", - "integrity": "sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.13.tgz", + "integrity": "sha512-acKF7EjqOR67ASIlDTupwkKM1eUisNAjaSduo5Cz+793ikfnpe7p4Q7B7EWU2PCoSTPWsQkR7hRUWEIZPiVLGA==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.12.1", - "@babel/helper-replace-supers": "^7.12.1", - "@babel/helper-simple-access": "^7.12.1", - "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/helper-validator-identifier": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.12.1", - "@babel/types": "^7.12.1", + "@babel/helper-module-imports": "^7.12.13", + "@babel/helper-replace-supers": "^7.12.13", + "@babel/helper-simple-access": "^7.12.13", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/helper-validator-identifier": "^7.12.11", + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.12.13", + "@babel/types": "^7.12.13", "lodash": "^4.17.19" } }, "@babel/helper-optimise-call-expression": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz", - "integrity": "sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz", + "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==", "dev": true, "requires": { - "@babel/types": "^7.12.10" + "@babel/types": "^7.12.13" } }, "@babel/helper-replace-supers": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz", - "integrity": "sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.13.tgz", + "integrity": "sha512-pctAOIAMVStI2TMLhozPKbf5yTEXc0OJa0eENheb4w09SrgOWEs+P4nTOZYJQCqs8JlErGLDPDJTiGIp3ygbLg==", "dev": true, "requires": { - "@babel/helper-member-expression-to-functions": "^7.12.7", - "@babel/helper-optimise-call-expression": "^7.12.10", - "@babel/traverse": "^7.12.10", - "@babel/types": "^7.12.11" + "@babel/helper-member-expression-to-functions": "^7.12.13", + "@babel/helper-optimise-call-expression": "^7.12.13", + "@babel/traverse": "^7.12.13", + "@babel/types": "^7.12.13" } }, "@babel/helper-simple-access": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.1.tgz", - "integrity": "sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.13.tgz", + "integrity": "sha512-0ski5dyYIHEfwpWGx5GPWhH35j342JaflmCeQmsPWcrOQDtCN6C1zKAVRFVbK53lPW2c9TsuLLSUDf0tIGJ5hA==", "dev": true, "requires": { - "@babel/types": "^7.12.1" + "@babel/types": "^7.12.13" } }, "@babel/helper-split-export-declaration": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", - "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", + "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", "dev": true, "requires": { - "@babel/types": "^7.12.11" + "@babel/types": "^7.12.13" } }, + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + }, "@babel/highlight": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", - "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.12.13.tgz", + "integrity": "sha512-kocDQvIbgMKlWxXe9fof3TQ+gkIPOUSEYhJjqUjvKMez3krV7vbzYCDq39Oj11UAVK7JqPVGQPlgE85dPNlQww==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/helper-validator-identifier": "^7.12.11", "chalk": "^2.0.0", "js-tokens": "^4.0.0" } }, "@babel/parser": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", - "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.16.tgz", + "integrity": "sha512-c/+u9cqV6F0+4Hpq01jnJO+GLp2DdT63ppz9Xa+6cHaajM9VFzK/iDXiKK65YtpeVwu+ctfS6iqlMqRgQRzeCw==", "dev": true }, "@babel/template": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", - "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", + "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", "dev": true, "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/parser": "^7.12.7", - "@babel/types": "^7.12.7" + "@babel/code-frame": "^7.12.13", + "@babel/parser": "^7.12.13", + "@babel/types": "^7.12.13" } }, "@babel/traverse": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", - "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.13.tgz", + "integrity": "sha512-3Zb4w7eE/OslI0fTp8c7b286/cQps3+vdLW3UcwC8VSJC6GbKn55aeVVu2QJNuCDoeKyptLOFrPq8WqZZBodyA==", "dev": true, "requires": { - "@babel/code-frame": "^7.12.11", - "@babel/generator": "^7.12.11", - "@babel/helper-function-name": "^7.12.11", - "@babel/helper-split-export-declaration": "^7.12.11", - "@babel/parser": "^7.12.11", - "@babel/types": "^7.12.12", + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.12.13", + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/parser": "^7.12.13", + "@babel/types": "^7.12.13", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.19" } }, "@babel/types": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", - "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.13.tgz", + "integrity": "sha512-oKrdZTld2im1z8bDwTOQvUbxKwE+854zc16qWZQlcTqMN00pWxHQ4ZeOq0yDMnisOpRykH2/5Qqcrk/OlbAjiQ==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", "to-fast-properties": "^2.0.0" - }, - "dependencies": { - "@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", - "dev": true - } } }, "debug": { @@ -3077,110 +3662,110 @@ } }, "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.1.tgz", - "integrity": "sha512-tB43uQ62RHcoDp9v2Nsf+dSM8sbNodbEicbQNA53zHz8pWUhsgHSJCGpt7daXxRydjb0KnfmB+ChXOv3oADp1Q==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.13.tgz", + "integrity": "sha512-Xsm8P2hr5hAxyYblrfACXpQKdQbx4m2df9/ZZSQ8MAhsadw06+jW7s9zsSw6he+mJZXRlVMyEnVktJo4zjk1WA==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.12.1" + "@babel/helper-create-regexp-features-plugin": "^7.12.13" } }, "@babel/plugin-transform-new-target": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.1.tgz", - "integrity": "sha512-+eW/VLcUL5L9IvJH7rT1sT0CzkdUTvPrXC2PXTn/7z7tXLBuKvezYbGdxD5WMRoyvyaujOq2fWoKl869heKjhw==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.13.tgz", + "integrity": "sha512-/KY2hbLxrG5GTQ9zzZSc3xWiOy379pIETEhbtzwZcw9rvuaVV4Fqy7BYGYOWZnaoXIQYbbJ0ziXLa/sKcGCYEQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" } }, "@babel/plugin-transform-object-super": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.1.tgz", - "integrity": "sha512-AvypiGJH9hsquNUn+RXVcBdeE3KHPZexWRdimhuV59cSoOt5kFBmqlByorAeUlGG2CJWd0U+4ZtNKga/TB0cAw==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.13.tgz", + "integrity": "sha512-JzYIcj3XtYspZDV8j9ulnoMPZZnF/Cj0LUxPOjR89BdBVx+zYJI9MdMIlUZjbXDX+6YVeS6I3e8op+qQ3BYBoQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-replace-supers": "^7.12.1" + "@babel/helper-plugin-utils": "^7.12.13", + "@babel/helper-replace-supers": "^7.12.13" }, "dependencies": { "@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", + "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", "dev": true, "requires": { - "@babel/highlight": "^7.10.4" + "@babel/highlight": "^7.12.13" } }, "@babel/generator": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", - "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", + "version": "7.12.15", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.15.tgz", + "integrity": "sha512-6F2xHxBiFXWNSGb7vyCUTBF8RCLY66rS0zEPcP8t/nQyXjha5EuK4z7H5o7fWG8B4M7y6mqVWq1J+1PuwRhecQ==", "dev": true, "requires": { - "@babel/types": "^7.12.11", + "@babel/types": "^7.12.13", "jsesc": "^2.5.1", "source-map": "^0.5.0" } }, "@babel/helper-function-name": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", - "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz", + "integrity": "sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.12.10", - "@babel/template": "^7.12.7", - "@babel/types": "^7.12.11" + "@babel/helper-get-function-arity": "^7.12.13", + "@babel/template": "^7.12.13", + "@babel/types": "^7.12.13" } }, "@babel/helper-get-function-arity": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", - "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", + "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", "dev": true, "requires": { - "@babel/types": "^7.12.10" + "@babel/types": "^7.12.13" } }, "@babel/helper-member-expression-to-functions": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", - "integrity": "sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw==", + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.16.tgz", + "integrity": "sha512-zYoZC1uvebBFmj1wFAlXwt35JLEgecefATtKp20xalwEK8vHAixLBXTGxNrVGEmTT+gzOThUgr8UEdgtalc1BQ==", "dev": true, "requires": { - "@babel/types": "^7.12.7" + "@babel/types": "^7.12.13" } }, "@babel/helper-optimise-call-expression": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz", - "integrity": "sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz", + "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==", "dev": true, "requires": { - "@babel/types": "^7.12.10" + "@babel/types": "^7.12.13" } }, "@babel/helper-replace-supers": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz", - "integrity": "sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.13.tgz", + "integrity": "sha512-pctAOIAMVStI2TMLhozPKbf5yTEXc0OJa0eENheb4w09SrgOWEs+P4nTOZYJQCqs8JlErGLDPDJTiGIp3ygbLg==", "dev": true, "requires": { - "@babel/helper-member-expression-to-functions": "^7.12.7", - "@babel/helper-optimise-call-expression": "^7.12.10", - "@babel/traverse": "^7.12.10", - "@babel/types": "^7.12.11" + "@babel/helper-member-expression-to-functions": "^7.12.13", + "@babel/helper-optimise-call-expression": "^7.12.13", + "@babel/traverse": "^7.12.13", + "@babel/types": "^7.12.13" } }, "@babel/helper-split-export-declaration": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", - "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", + "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", "dev": true, "requires": { - "@babel/types": "^7.12.11" + "@babel/types": "^7.12.13" } }, "@babel/helper-validator-identifier": { @@ -3190,54 +3775,54 @@ "dev": true }, "@babel/highlight": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", - "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.12.13.tgz", + "integrity": "sha512-kocDQvIbgMKlWxXe9fof3TQ+gkIPOUSEYhJjqUjvKMez3krV7vbzYCDq39Oj11UAVK7JqPVGQPlgE85dPNlQww==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/helper-validator-identifier": "^7.12.11", "chalk": "^2.0.0", "js-tokens": "^4.0.0" } }, "@babel/parser": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", - "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.16.tgz", + "integrity": "sha512-c/+u9cqV6F0+4Hpq01jnJO+GLp2DdT63ppz9Xa+6cHaajM9VFzK/iDXiKK65YtpeVwu+ctfS6iqlMqRgQRzeCw==", "dev": true }, "@babel/template": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", - "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", + "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", "dev": true, "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/parser": "^7.12.7", - "@babel/types": "^7.12.7" + "@babel/code-frame": "^7.12.13", + "@babel/parser": "^7.12.13", + "@babel/types": "^7.12.13" } }, "@babel/traverse": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", - "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.13.tgz", + "integrity": "sha512-3Zb4w7eE/OslI0fTp8c7b286/cQps3+vdLW3UcwC8VSJC6GbKn55aeVVu2QJNuCDoeKyptLOFrPq8WqZZBodyA==", "dev": true, "requires": { - "@babel/code-frame": "^7.12.11", - "@babel/generator": "^7.12.11", - "@babel/helper-function-name": "^7.12.11", - "@babel/helper-split-export-declaration": "^7.12.11", - "@babel/parser": "^7.12.11", - "@babel/types": "^7.12.12", + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.12.13", + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/parser": "^7.12.13", + "@babel/types": "^7.12.13", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.19" } }, "@babel/types": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", - "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.13.tgz", + "integrity": "sha512-oKrdZTld2im1z8bDwTOQvUbxKwE+854zc16qWZQlcTqMN00pWxHQ4ZeOq0yDMnisOpRykH2/5Qqcrk/OlbAjiQ==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", @@ -3263,39 +3848,39 @@ } }, "@babel/plugin-transform-parameters": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.12.1.tgz", - "integrity": "sha512-xq9C5EQhdPK23ZeCdMxl8bbRnAgHFrw5EOC3KJUsSylZqdkCaFEXxGSBuTSObOpiiHHNyb82es8M1QYgfQGfNg==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.12.13.tgz", + "integrity": "sha512-e7QqwZalNiBRHCpJg/P8s/VJeSRYgmtWySs1JwvfwPqhBbiWfOcHDKdeAi6oAyIimoKWBlwc8oTgbZHdhCoVZA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" } }, "@babel/plugin-transform-property-literals": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.1.tgz", - "integrity": "sha512-6MTCR/mZ1MQS+AwZLplX4cEySjCpnIF26ToWo942nqn8hXSm7McaHQNeGx/pt7suI1TWOWMfa/NgBhiqSnX0cQ==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.13.tgz", + "integrity": "sha512-nqVigwVan+lR+g8Fj8Exl0UQX2kymtjcWfMOYM1vTYEKujeyv2SkMgazf2qNcK7l4SDiKyTA/nHCPqL4e2zo1A==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" } }, "@babel/plugin-transform-regenerator": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.12.1.tgz", - "integrity": "sha512-gYrHqs5itw6i4PflFX3OdBPMQdPbF4bj2REIUxlMRUFk0/ZOAIpDFuViuxPjUL7YC8UPnf+XG7/utJvqXdPKng==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.12.13.tgz", + "integrity": "sha512-lxb2ZAvSLyJ2PEe47hoGWPmW22v7CtSl9jW8mingV4H2sEX/JOcrAj2nPuGWi56ERUm2bUpjKzONAuT6HCn2EA==", "dev": true, "requires": { "regenerator-transform": "^0.14.2" } }, "@babel/plugin-transform-reserved-words": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.1.tgz", - "integrity": "sha512-pOnUfhyPKvZpVyBHhSBoX8vfA09b7r00Pmm1sH+29ae2hMTKVmSp4Ztsr8KBKjLjx17H0eJqaRC3bR2iThM54A==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.13.tgz", + "integrity": "sha512-xhUPzDXxZN1QfiOy/I5tyye+TRz6lA7z6xaT4CLOjPRMVg1ldRf0LHw0TDBpYL4vG78556WuHdyO9oi5UmzZBg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" } }, "@babel/plugin-transform-runtime": { @@ -3310,12 +3895,12 @@ }, "dependencies": { "@babel/helper-module-imports": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz", - "integrity": "sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.13.tgz", + "integrity": "sha512-NGmfvRp9Rqxy0uHSSVP+SRIW1q31a7Ji10cLBcqSDUngGentY4FRiHOFZFE1CLU5eiL0oE8reH7Tg1y99TDM/g==", "dev": true, "requires": { - "@babel/types": "^7.12.5" + "@babel/types": "^7.12.13" } }, "@babel/helper-validator-identifier": { @@ -3325,9 +3910,9 @@ "dev": true }, "@babel/types": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", - "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.13.tgz", + "integrity": "sha512-oKrdZTld2im1z8bDwTOQvUbxKwE+854zc16qWZQlcTqMN00pWxHQ4ZeOq0yDMnisOpRykH2/5Qqcrk/OlbAjiQ==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", @@ -3338,68 +3923,68 @@ } }, "@babel/plugin-transform-shorthand-properties": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.1.tgz", - "integrity": "sha512-GFZS3c/MhX1OusqB1MZ1ct2xRzX5ppQh2JU1h2Pnfk88HtFTM+TWQqJNfwkmxtPQtb/s1tk87oENfXJlx7rSDw==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.13.tgz", + "integrity": "sha512-xpL49pqPnLtf0tVluuqvzWIgLEhuPpZzvs2yabUHSKRNlN7ScYU7aMlmavOeyXJZKgZKQRBlh8rHbKiJDraTSw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" } }, "@babel/plugin-transform-spread": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.12.1.tgz", - "integrity": "sha512-vuLp8CP0BE18zVYjsEBZ5xoCecMK6LBMMxYzJnh01rxQRvhNhH1csMMmBfNo5tGpGO+NhdSNW2mzIvBu3K1fng==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.12.13.tgz", + "integrity": "sha512-dUCrqPIowjqk5pXsx1zPftSq4sT0aCeZVAxhdgs3AMgyaDmoUT0G+5h3Dzja27t76aUEIJWlFgPJqJ/d4dbTtg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-plugin-utils": "^7.12.13", "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1" } }, "@babel/plugin-transform-sticky-regex": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.7.tgz", - "integrity": "sha512-VEiqZL5N/QvDbdjfYQBhruN0HYjSPjC4XkeqW4ny/jNtH9gcbgaqBIXYEZCNnESMAGs0/K/R7oFGMhOyu/eIxg==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.13.tgz", + "integrity": "sha512-Jc3JSaaWT8+fr7GRvQP02fKDsYk4K/lYwWq38r/UGfaxo89ajud321NH28KRQ7xy1Ybc0VUE5Pz8psjNNDUglg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" } }, "@babel/plugin-transform-template-literals": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.12.1.tgz", - "integrity": "sha512-b4Zx3KHi+taXB1dVRBhVJtEPi9h1THCeKmae2qP0YdUHIFhVjtpqqNfxeVAa1xeHVhAy4SbHxEwx5cltAu5apw==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.12.13.tgz", + "integrity": "sha512-arIKlWYUgmNsF28EyfmiQHJLJFlAJNYkuQO10jL46ggjBpeb2re1P9K9YGxNJB45BqTbaslVysXDYm/g3sN/Qg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" } }, "@babel/plugin-transform-typeof-symbol": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.10.tgz", - "integrity": "sha512-JQ6H8Rnsogh//ijxspCjc21YPd3VLVoYtAwv3zQmqAt8YGYUtdo5usNhdl4b9/Vir2kPFZl6n1h0PfUz4hJhaA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.13.tgz", + "integrity": "sha512-eKv/LmUJpMnu4npgfvs3LiHhJua5fo/CysENxa45YCQXZwKnGCQKAg87bvoqSW1fFT+HA32l03Qxsm8ouTY3ZQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" } }, "@babel/plugin-transform-unicode-escapes": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.1.tgz", - "integrity": "sha512-I8gNHJLIc7GdApm7wkVnStWssPNbSRMPtgHdmH3sRM1zopz09UWPS4x5V4n1yz/MIWTVnJ9sp6IkuXdWM4w+2Q==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.13.tgz", + "integrity": "sha512-0bHEkdwJ/sN/ikBHfSmOXPypN/beiGqjo+o4/5K+vxEFNPRPdImhviPakMKG4x96l85emoa0Z6cDflsdBusZbw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" } }, "@babel/plugin-transform-unicode-regex": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.1.tgz", - "integrity": "sha512-SqH4ClNngh/zGwHZOOQMTD+e8FGWexILV+ePMyiDJttAWRh5dhDL8rcl5lSgU3Huiq6Zn6pWTMvdPAb21Dwdyg==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.13.tgz", + "integrity": "sha512-mDRzSNY7/zopwisPZ5kM9XKCfhchqIYwAKRERtEnhYscZB79VRekuRSoYbN0+KVe3y8+q1h6A4svXtP7N+UoCA==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-create-regexp-features-plugin": "^7.12.13", + "@babel/helper-plugin-utils": "^7.12.13" } }, "@babel/preset-env": { @@ -3477,12 +4062,12 @@ }, "dependencies": { "@babel/helper-module-imports": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz", - "integrity": "sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.13.tgz", + "integrity": "sha512-NGmfvRp9Rqxy0uHSSVP+SRIW1q31a7Ji10cLBcqSDUngGentY4FRiHOFZFE1CLU5eiL0oE8reH7Tg1y99TDM/g==", "dev": true, "requires": { - "@babel/types": "^7.12.5" + "@babel/types": "^7.12.13" } }, "@babel/helper-validator-identifier": { @@ -3492,9 +4077,9 @@ "dev": true }, "@babel/types": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", - "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.13.tgz", + "integrity": "sha512-oKrdZTld2im1z8bDwTOQvUbxKwE+854zc16qWZQlcTqMN00pWxHQ4ZeOq0yDMnisOpRykH2/5Qqcrk/OlbAjiQ==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", @@ -3614,9 +4199,9 @@ } }, "@istanbuljs/schema": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", - "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==", + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true }, "@jsdevtools/coverage-istanbul-loader": { @@ -3633,14 +4218,47 @@ } }, "@ngtools/webpack": { - "version": "11.1.2", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-11.1.2.tgz", - "integrity": "sha512-x/HVx4doKu4gAwGGk+C89JCFe5GF8Te7I7uvwMTqEXr+Ua9YHYvN/q2IwLdhIXPB4ilBSIjrb9zm05yBvBTAeg==", + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-11.2.0.tgz", + "integrity": "sha512-2KYaA/fIw863jydXDolWp4kUNLODVIKs2834vW+oztocnYFe/z4dTz6rArKFUCixMCu12ieXrjAetzGA564bsg==", "dev": true, "requires": { - "@angular-devkit/core": "11.1.2", - "enhanced-resolve": "5.6.0", + "@angular-devkit/core": "11.2.0", + "enhanced-resolve": "5.7.0", "webpack-sources": "2.2.0" + }, + "dependencies": { + "@angular-devkit/core": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-11.2.0.tgz", + "integrity": "sha512-qqYEH8m/bwpngoLDMFuth8ykvoHxQ3aHHnAWfRXz9NXydwSfathG0VSYCctB126sK39JKIn+xq16CQAExxNu+Q==", + "dev": true, + "requires": { + "ajv": "6.12.6", + "fast-json-stable-stringify": "2.1.0", + "magic-string": "0.25.7", + "rxjs": "6.6.3", + "source-map": "0.7.3" + } + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + } } }, "@ngx-translate/core": { @@ -3692,9 +4310,9 @@ "dev": true }, "@npmcli/git": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-2.0.4.tgz", - "integrity": "sha512-OJZCmJ9DNn1cz9HPXXsPmUBnqaArot3CGYo63CyajHQk+g87rPXVOJByGsskQJhPsUUEXJcsZ2Q6bWd2jSwnBA==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-2.0.6.tgz", + "integrity": "sha512-a1MnTfeRPBaKbFY07fd+6HugY1WAkKJzdiJvlRub/9o5xz2F/JtPacZZapx5zRJUQFIzSL677vmTSxEcDMrDbg==", "dev": true, "requires": { "@npmcli/promise-spawn": "^1.1.0", @@ -3702,7 +4320,7 @@ "mkdirp": "^1.0.3", "npm-pick-manifest": "^6.0.0", "promise-inflight": "^1.0.1", - "promise-retry": "^1.1.1", + "promise-retry": "^2.0.1", "semver": "^7.3.2", "unique-filename": "^1.1.1", "which": "^2.0.2" @@ -3714,6 +4332,16 @@ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true }, + "promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "dev": true, + "requires": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + } + }, "semver": { "version": "7.3.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", @@ -3735,15 +4363,13 @@ } }, "@npmcli/installed-package-contents": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-1.0.5.tgz", - "integrity": "sha512-aKIwguaaqb6ViwSOFytniGvLPb9SMCUm39TgM3SfUo7n0TxUMbwoXfpwyvQ4blm10lzbAwTsvjr7QZ85LvTi4A==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-1.0.7.tgz", + "integrity": "sha512-9rufe0wnJusCQoLpV9ZPKIVP55itrM5BxOXs10DmdbRfgWtHy1LDyskbwRnBghuB0PrF7pNPOqREVtpz4HqzKw==", "dev": true, "requires": { "npm-bundled": "^1.1.1", - "npm-normalize-package-bin": "^1.0.1", - "read-package-json-fast": "^1.1.1", - "readdir-scoped-modules": "^1.1.0" + "npm-normalize-package-bin": "^1.0.1" } }, "@npmcli/move-file": { @@ -3774,9 +4400,9 @@ } }, "@npmcli/node-gyp": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-1.0.1.tgz", - "integrity": "sha512-pBqoKPWmuk9iaEcXlLBVRIA6I1kG9JiICU+sG0NuD6NAR461F+02elHJS4WkQxHW2W5rnsfvP/ClKwmsZ9RaaA==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-1.0.2.tgz", + "integrity": "sha512-yrJUe6reVMpktcvagumoqD9r08fH1iRo01gn1u0zoCApa9lnZGEigVKUd2hzsCId4gdtkZZIVscLhNxMECKgRg==", "dev": true }, "@npmcli/promise-spawn": { @@ -3789,17 +4415,29 @@ } }, "@npmcli/run-script": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-1.8.1.tgz", - "integrity": "sha512-G8c86g9cQHyRINosIcpovzv0BkXQc3urhL1ORf3KTe4TS4UBsg2O4Z2feca/W3pfzdHEJzc83ETBW4aKbb3SaA==", + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-1.8.3.tgz", + "integrity": "sha512-ELPGWAVU/xyU+A+H3pEPj0QOvYwLTX71RArXcClFzeiyJ/b/McsZ+d0QxpznvfFtZzxGN/gz/1cvlqICR4/suQ==", "dev": true, "requires": { - "@npmcli/node-gyp": "^1.0.0", - "@npmcli/promise-spawn": "^1.3.0", + "@npmcli/node-gyp": "^1.0.2", + "@npmcli/promise-spawn": "^1.3.2", "infer-owner": "^1.0.4", "node-gyp": "^7.1.0", "puka": "^1.0.1", - "read-package-json-fast": "^1.1.3" + "read-package-json-fast": "^2.0.1" + }, + "dependencies": { + "read-package-json-fast": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-2.0.1.tgz", + "integrity": "sha512-bp6z0tdgLy9KzdfENDIw/53HWAolOVoQTRWXv7PUiqAo3YvvoUVeLr7RWPWq+mu7KUOu9kiT4DvxhUgNUBsvug==", + "dev": true, + "requires": { + "json-parse-even-better-errors": "^2.3.0", + "npm-normalize-package-bin": "^1.0.1" + } + } } }, "@protobufjs/aspromise": { @@ -3857,32 +4495,90 @@ "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" }, "@schematics/angular": { - "version": "11.1.2", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-11.1.2.tgz", - "integrity": "sha512-ZhaB/QBwfWsvZYJplLH8VK/7vnFpUbk1nptjC106K/I38xlmWdB4pStLJK94eyJk0KlItnsPvE0a9KuLPKA/Ow==", + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-11.2.0.tgz", + "integrity": "sha512-PtbyZ7TEEEae9Y5siSZYigWyk8iOSjZ10ThA7tRxm8gdcLjGimyyKr5TyjufIAvrXIYnBXNLgPkZG6s5CQIEyw==", "dev": true, "requires": { - "@angular-devkit/core": "11.1.2", - "@angular-devkit/schematics": "11.1.2", + "@angular-devkit/core": "11.2.0", + "@angular-devkit/schematics": "11.2.0", "jsonc-parser": "3.0.0" + }, + "dependencies": { + "@angular-devkit/core": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-11.2.0.tgz", + "integrity": "sha512-qqYEH8m/bwpngoLDMFuth8ykvoHxQ3aHHnAWfRXz9NXydwSfathG0VSYCctB126sK39JKIn+xq16CQAExxNu+Q==", + "dev": true, + "requires": { + "ajv": "6.12.6", + "fast-json-stable-stringify": "2.1.0", + "magic-string": "0.25.7", + "rxjs": "6.6.3", + "source-map": "0.7.3" + } + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + } } }, "@schematics/update": { - "version": "0.1101.2", - "resolved": "https://registry.npmjs.org/@schematics/update/-/update-0.1101.2.tgz", - "integrity": "sha512-WwMsIkhR3hq7gvfB5HsuTK2Sz9iZmpz0/AiFYRJbX+mXL/KgONcridyorW45Dg1Q2sRXVGiAUxWsQYzjmeLO7g==", + "version": "0.1102.0", + "resolved": "https://registry.npmjs.org/@schematics/update/-/update-0.1102.0.tgz", + "integrity": "sha512-2hFt/2iPe6LqQvzYj4HvQ8us0e0lBU75rSK2yY6VfiZWR/qo7yk99YKI7JWFTLvLsNbhNnSG/9opXJHqqUoc3g==", "dev": true, "requires": { - "@angular-devkit/core": "11.1.2", - "@angular-devkit/schematics": "11.1.2", + "@angular-devkit/core": "11.2.0", + "@angular-devkit/schematics": "11.2.0", "@yarnpkg/lockfile": "1.1.0", "ini": "2.0.0", "npm-package-arg": "^8.0.0", - "pacote": "11.1.14", + "pacote": "11.2.4", "semver": "7.3.4", "semver-intersect": "1.4.0" }, "dependencies": { + "@angular-devkit/core": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-11.2.0.tgz", + "integrity": "sha512-qqYEH8m/bwpngoLDMFuth8ykvoHxQ3aHHnAWfRXz9NXydwSfathG0VSYCctB126sK39JKIn+xq16CQAExxNu+Q==", + "dev": true, + "requires": { + "ajv": "6.12.6", + "fast-json-stable-stringify": "2.1.0", + "magic-string": "0.25.7", + "rxjs": "6.6.3", + "source-map": "0.7.3" + } + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, "ini": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", @@ -3897,6 +4593,12 @@ "requires": { "lru-cache": "^6.0.0" } + }, + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true } } }, @@ -3926,9 +4628,9 @@ "dev": true }, "@types/bytebuffer": { - "version": "5.0.41", - "resolved": "https://registry.npmjs.org/@types/bytebuffer/-/bytebuffer-5.0.41.tgz", - "integrity": "sha512-Mdrv4YcaHvpkx25ksqqFaezktx3yZRcd51GZY0rY/9avyaqZdiT/GiWRhfrJhMpgzXqTOSHgGvsumGxJFNiZZA==", + "version": "5.0.42", + "resolved": "https://registry.npmjs.org/@types/bytebuffer/-/bytebuffer-5.0.42.tgz", + "integrity": "sha512-lEgKojWUAc/MG2t649oZS5AfYFP2xRNPoDuwDBlBMjHXd8MaGPgFgtCXUK7inZdBOygmVf10qxc1Us8GXC96aw==", "requires": { "@types/long": "*", "@types/node": "*" @@ -3953,9 +4655,9 @@ "dev": true }, "@types/cors": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.9.tgz", - "integrity": "sha512-zurD1ibz21BRlAOIKP8yhrxlqKx6L9VCwkB5kMiP6nZAhoF5MvC7qS1qPA7nRcr1GJolfkQC7/EAL4hdYejLtg==", + "version": "2.8.10", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.10.tgz", + "integrity": "sha512-C7srjHiVG3Ey1nR6d511dtDkCEjxuN9W1HWAEjGq8kpcwmNM6JJkpC0xvabM7BXTG2wDq8Eu33iH9aQKa7IvLQ==", "dev": true }, "@types/file-saver": { @@ -4026,9 +4728,9 @@ "dev": true }, "@types/node": { - "version": "14.14.22", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.22.tgz", - "integrity": "sha512-g+f/qj/cNcqKkc3tFqlXOYjrmZA+jNBiDzbP3kH+B+otKFqAdPgVTGP1IeKRdMml/aE69as5S4FqtxAbl+LaMw==" + "version": "14.14.28", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.28.tgz", + "integrity": "sha512-lg55ArB+ZiHHbBBttLpzD07akz0QPrZgUODNakeC09i62dnrywr9mFErHuaPlB6I7z+sEbK+IYmplahvplCj2g==" }, "@types/normalize-package-data": { "version": "2.4.0", @@ -4328,9 +5030,9 @@ } }, "agentkeepalive": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.1.3.tgz", - "integrity": "sha512-wn8fw19xKZwdGPO47jivonaHRTd+nGOMP1z11sgGeQzDy2xd5FG0R67dIMcKHDE2cJ5y+YXV30XVGUBPRSY7Hg==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.1.4.tgz", + "integrity": "sha512-+V/rGa3EuU74H6wR04plBb7Ks10FbtUQgRj/FQOG7uUIEuaINI+AiqJR1k6t3SVNs7o7ZjIdus6706qqzVq8jQ==", "dev": true, "requires": { "debug": "^4.1.0", @@ -4589,12 +5291,6 @@ "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", "dev": true }, - "asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", - "dev": true - }, "ascli": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/ascli/-/ascli-1.0.1.tgz", @@ -5923,12 +6619,12 @@ "dev": true }, "copy-anything": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.1.tgz", - "integrity": "sha512-lA57e7viQHOdPQcrytv5jFeudZZOXuyk47lZym279FiDQ8jeZomXiGuVf6ffMKkJ+3TIai3J1J3yi6M+/4U35g==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.3.tgz", + "integrity": "sha512-GK6QUtisv4fNS+XcI7shX0Gx9ORg7QqIznyfho79JTnX1XhLiyZHfftvGiziqzRiEi/Bjhgpi+D2o7HxJFPnDQ==", "dev": true, "requires": { - "is-what": "^3.7.1" + "is-what": "^3.12.0" } }, "copy-concurrently": { @@ -6015,9 +6711,9 @@ } }, "core-js": { - "version": "3.8.2", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.8.2.tgz", - "integrity": "sha512-FfApuSRgrR6G5s58casCBd9M2k+4ikuu4wbW6pJyYU7bd9zvFc9qf7vr5xmrZOhT9nn+8uwlH1oRR9jTnFoA3A==", + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.8.3.tgz", + "integrity": "sha512-KPYXeVZYemC2TkNEkX/01I+7yd+nX3KddKwZ1Ww7SKWdI2wQprSgLmrTddT8nw92AjEklTsPBoSdQBhbI1bQ6Q==", "dev": true }, "core-js-compat": { @@ -6044,15 +6740,15 @@ } }, "caniuse-lite": { - "version": "1.0.30001181", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001181.tgz", - "integrity": "sha512-m5ul/ARCX50JB8BSNM+oiPmQrR5UmngaQ3QThTTp5HcIIQGP/nPBs82BYLE+tigzm3VW+F4BJIhUyaVtEweelQ==", + "version": "1.0.30001187", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001187.tgz", + "integrity": "sha512-w7/EP1JRZ9552CyrThUnay2RkZ1DXxKe/Q2swTC4+LElLh9RRYrL1Z+27LlakB8kzY0fSmHw9mc7XYDUKAKWMA==", "dev": true }, "electron-to-chromium": { - "version": "1.3.649", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.649.tgz", - "integrity": "sha512-ojGDupQ3UMkvPWcTICe4JYe17+o9OLiFMPoduoR72Zp2ILt1mRVeqnxBEd6s/ptekrnsFU+0A4lStfBe/wyG/A==", + "version": "1.3.664", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.664.tgz", + "integrity": "sha512-yb8LrTQXQnh9yhnaIHLk6CYugF/An50T20+X0h++hjjhVfgSp1DGoMSYycF8/aD5eiqS4QwaNhiduFvK8rifRg==", "dev": true }, "escalade": { @@ -6339,9 +7035,9 @@ "dev": true }, "postcss": { - "version": "8.2.4", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.2.4.tgz", - "integrity": "sha512-kRFftRoExRVXZlwUuay9iC824qmXPcQQVzAjbCCgjpXnkdMCJYBu2gTwAaFBzv8ewND6O8xFb3aELmEkh9zTzg==", + "version": "8.2.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.2.6.tgz", + "integrity": "sha512-xpB8qYxgPuly166AGlpRjUdEYtmOWx2iCwGmrv4vqZL9YPVviDVPZPRXxnXr6xPZOdxQ9lp3ZBFCRgWJ7LE3Sg==", "dev": true, "requires": { "colorette": "^1.2.1", @@ -6645,12 +7341,6 @@ "ms": "^2.1.1" } }, - "debuglog": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/debuglog/-/debuglog-1.0.1.tgz", - "integrity": "sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI=", - "dev": true - }, "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", @@ -6862,16 +7552,6 @@ "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==", "dev": true }, - "dezalgo": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.3.tgz", - "integrity": "sha1-f3Qt4Gb8dIvI24IFad3c5Jvw1FY=", - "dev": true, - "requires": { - "asap": "^2.0.0", - "wrappy": "1" - } - }, "di": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", @@ -7093,18 +7773,18 @@ "dev": true }, "elliptic": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", - "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", "dev": true, "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", + "bn.js": "^4.11.9", + "brorand": "^1.1.0", "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" }, "dependencies": { "bn.js": { @@ -7165,9 +7845,9 @@ } }, "engine.io": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-4.1.0.tgz", - "integrity": "sha512-vW7EAtn0HDQ4MtT5QbmCHF17TaYLONv2/JwdYsq9USPRZVM4zG7WB3k0Nc321z8EuSOlhGokrYlYx4176QhD0A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-4.1.1.tgz", + "integrity": "sha512-t2E9wLlssQjGw0nluF6aYyfX8LwYU8Jj0xct+pAhfWfv/YrBn6TSNtEYsgxHIfaMqfrLx07czcMg9bMN6di+3w==", "dev": true, "requires": { "accepts": "~1.3.4", @@ -7195,9 +7875,9 @@ } }, "ws": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.2.tgz", - "integrity": "sha512-T4tewALS3+qsrpGI/8dqNMLIVdq/g/85U98HPMa6F0m6xTbvhXU6RCQLqPH3+SlomNV/LdY6RXEbBpMH6EOJnA==", + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.3.tgz", + "integrity": "sha512-hr6vCR76GsossIRsr8OLR9acVVm1jyfEWvhbNjtgPOrfvAlKzvyeg/P6r8RuDjRyrcQoPQT7K0DGEPc7Ae6jzA==", "dev": true } } @@ -7212,9 +7892,9 @@ } }, "enhanced-resolve": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.6.0.tgz", - "integrity": "sha512-C3GGDfFZmqUa21o10YRKbZN60DPl0HyXKXxoEnQMWso9u7KMU23L7CBHfr/rVxORddY/8YQZaU2MZ1ewTS8Pcw==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.7.0.tgz", + "integrity": "sha512-6njwt/NsZFUKhM6j9U8hzVyD4E4r0x7NQzhTCbcWOJ0IQjNSAoalWmb0AE51Wn+fwan5qVESWi7t2ToBxs9vrw==", "dev": true, "requires": { "graceful-fs": "^4.2.4", @@ -7222,9 +7902,9 @@ }, "dependencies": { "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", "dev": true } } @@ -7248,9 +7928,9 @@ "dev": true }, "err-code": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/err-code/-/err-code-1.1.2.tgz", - "integrity": "sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA=", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", "dev": true }, "errno": { @@ -7614,9 +8294,9 @@ }, "dependencies": { "type": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/type/-/type-2.1.0.tgz", - "integrity": "sha512-G9absDWvhAWCV2gmF1zKud3OyC61nZDwWvBL2DApaVFogI07CprggiQAOOjvp2NRjYWFzPyu7vwtDrQFq8jeSA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-2.2.0.tgz", + "integrity": "sha512-M/u37b4oSGlusaU8ZB96BfFPWQ8MbsZYXB+kXGMiDj6IKinkcNaQvmirBuWj8mAXqP6LYn1rQvbTYum3yPhaOA==", "dev": true } } @@ -8221,9 +8901,9 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" }, "get-intrinsic": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.0.tgz", - "integrity": "sha512-M11rgtQp5GZMZzDL7jLTNxbDfurpzuau5uqRWDPvlHjfvg3TdScAZo96GLvhMjImrmR8uAt0FS2RLoMrfWGKlg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", "dev": true, "requires": { "function-bind": "^1.1.1", @@ -8367,15 +9047,15 @@ "dev": true }, "grpc": { - "version": "1.24.3", - "resolved": "https://registry.npmjs.org/grpc/-/grpc-1.24.3.tgz", - "integrity": "sha512-EDemzuZTfhM0hgrXqC4PtR76O3t+hTIYJYR5vgiW0yt2WJqo4mhxUqZUirzUQz34Psz7dbLp38C6Cl7Ij2vXRQ==", + "version": "1.24.5", + "resolved": "https://registry.npmjs.org/grpc/-/grpc-1.24.5.tgz", + "integrity": "sha512-+dY6lfLPovblJO5QitBQM2L67efI5JjBzCqJQURSINPzoFHos+5bs4DHwtes7BF+dkx5eN3fx/VUFRCmWTsE7g==", "requires": { "@types/bytebuffer": "^5.0.40", "lodash.camelcase": "^4.3.0", "lodash.clone": "^4.5.0", "nan": "^2.13.2", - "node-pre-gyp": "^0.15.0", + "node-pre-gyp": "^0.16.0", "protobufjs": "^5.0.3" }, "dependencies": { @@ -8544,10 +9224,13 @@ } }, "hosted-git-info": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.5.tgz", - "integrity": "sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg==", - "dev": true + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.8.tgz", + "integrity": "sha512-aXpmwoOhRBrw6X3j0h5RloK4x1OzsxMPyxqIHyNfSe2pypkVTZFpEiRoSipPEPlMrh0HW/XsjkJ5WgnCirpNUw==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } }, "hpack.js": { "version": "2.1.6", @@ -9429,11 +10112,12 @@ } }, "is-regex": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", - "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz", + "integrity": "sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==", "dev": true, "requires": { + "call-bind": "^1.0.2", "has-symbols": "^1.0.1" } }, @@ -9873,9 +10557,9 @@ } }, "karma": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/karma/-/karma-6.0.3.tgz", - "integrity": "sha512-dmiLQdsNAvnbV1G6VvUK7Cl5xpwiMisZNT8MjBtOo49jKlnZSWLxQIemuLT8sGSzvx5IGgMfMQEtf/CALiUEVQ==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/karma/-/karma-6.1.1.tgz", + "integrity": "sha512-vVDFxFGAsclgmFjZA/qGw5xqWdZIWxVD7xLyCukYUYd5xs/uGzYbXGOT5zOruVBQleKEmXIr4H2hzGCTn+M9Cg==", "dev": true, "requires": { "body-parser": "^1.19.0", @@ -9896,7 +10580,7 @@ "qjobs": "^1.2.0", "range-parser": "^1.2.1", "rimraf": "^3.0.2", - "socket.io": "^3.0.4", + "socket.io": "^3.1.0", "source-map": "^0.6.1", "tmp": "0.2.1", "ua-parser-js": "^0.7.23", @@ -9951,9 +10635,9 @@ "dev": true }, "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", "dev": true }, "is-fullwidth-code-point": { @@ -10039,9 +10723,9 @@ } }, "yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "version": "20.2.5", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.5.tgz", + "integrity": "sha512-jYRGS3zWy20NtDtK2kBgo/TlAoy5YUuhD9/LZ7z7W4j1Fdw2cqD0xEEclf8fxc8xjD6X5Qr+qQQwCEsP8iRiYg==", "dev": true } } @@ -10111,9 +10795,9 @@ "dev": true }, "known-css-properties": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.20.0.tgz", - "integrity": "sha512-URvsjaA9ypfreqJ2/ylDr5MUERhJZ+DhguoWRr2xgS5C7aGCalXo+ewL+GixgKBfhT2vuL02nbIgNGqVWgTOYw==", + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.21.0.tgz", + "integrity": "sha512-sZLUnTqimCkvkgRS+kbPlYW5o8q5w1cu+uIisKpEWkj31I8mx8kNG162DwRav8Zirkva6N5uoFsm9kzK4mUXjw==", "dev": true }, "lcid": { @@ -10125,9 +10809,9 @@ } }, "less": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/less/-/less-4.1.0.tgz", - "integrity": "sha512-w1Ag/f34g7LwtQ/sMVSGWIyZx+gG9ZOAEtyxeX1fG75is6BMyC2lD5kG+1RueX7PkAvlQBm2Lf2aN2j0JbVr2A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/less/-/less-4.1.1.tgz", + "integrity": "sha512-w09o8tZFPThBscl5d0Ggp3RcrKIouBoQscnOMgFH3n5V3kN/CXGHNfCkRPtxJk6nKryDXaV9aHLK55RXuH4sAw==", "dev": true, "requires": { "copy-anything": "^2.0.1", @@ -10444,9 +11128,9 @@ "dev": true }, "make-fetch-happen": { - "version": "8.0.13", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-8.0.13.tgz", - "integrity": "sha512-rQ5NijwwdU8tIaBrpTtSVrNCcAJfyDRcKBC76vOQlyJX588/88+TE+UpjWl4BgG7gCkp29wER7xcRqkeg+x64Q==", + "version": "8.0.14", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-8.0.14.tgz", + "integrity": "sha512-EsS89h6l4vbfJEtBZnENTOFk8mCRpY5ru36Xe5bcX1KYIli2mkSHqoFsp5O1wMDvTJJzxe/4THpCTtygjeeGWQ==", "dev": true, "requires": { "agentkeepalive": "^4.1.3", @@ -10461,7 +11145,7 @@ "minipass-fetch": "^1.3.2", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", - "promise-retry": "^1.1.1", + "promise-retry": "^2.0.1", "socks-proxy-agent": "^5.0.0", "ssri": "^8.0.0" }, @@ -10493,6 +11177,16 @@ "agent-base": "6", "debug": "4" } + }, + "promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "dev": true, + "requires": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + } } } }, @@ -10535,9 +11229,9 @@ } }, "mdast-util-from-markdown": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.4.tgz", - "integrity": "sha512-jj891B5pV2r63n2kBTFh8cRI2uR9LQHsXG1zSDqfhXkIlDzrTcIlbB5+5aaYEkl8vOPIOPLf8VT7Ere1wWTMdw==", + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz", + "integrity": "sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==", "dev": true, "requires": { "@types/mdast": "^3.0.0", @@ -10548,9 +11242,9 @@ } }, "mdast-util-to-markdown": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-0.6.2.tgz", - "integrity": "sha512-iRczns6WMvu0hUw02LXsPDJshBIwtUPbvHBWo19IQeU0YqmzlA8Pd30U8V7uiI0VPkxzS7A/NXBXH6u+HS87Zg==", + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-0.6.5.tgz", + "integrity": "sha512-XeV9sDE7ZlOQvs45C9UKMtfTcctcaj/pGwH8YLbMHoMOXNNCn2LsqVQOqrF1+/NU8lKDAqozme9SCXWyo9oAcQ==", "dev": true, "requires": { "@types/unist": "^2.0.0", @@ -10641,46 +11335,6 @@ "yargs-parser": "^20.2.3" }, "dependencies": { - "hosted-git-info": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.7.tgz", - "integrity": "sha512-fWqc0IcuXs+BmE9orLDyVykAG9GJtGLGuZAAqgcckPgv5xad4AcXGIv8galtQvlwutxSlaMcdw7BUtq2EIvqCQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "normalize-package-data": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.0.tgz", - "integrity": "sha512-6lUjEI0d3v6kFrtgA/lOx4zHCWULXsFNIjHolnZCKCTLA6m/G625cdn3O7eNmT0iD3jfo6HZ9cdImGZwf21prw==", - "dev": true, - "requires": { - "hosted-git-info": "^3.0.6", - "resolve": "^1.17.0", - "semver": "^7.3.2", - "validate-npm-package-license": "^3.0.1" - } - }, - "resolve": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", - "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", - "dev": true, - "requires": { - "is-core-module": "^2.1.0", - "path-parse": "^1.0.6" - } - }, - "semver": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", - "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, "type-fest": { "version": "0.18.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", @@ -10688,9 +11342,9 @@ "dev": true }, "yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "version": "20.2.5", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.5.tgz", + "integrity": "sha512-jYRGS3zWy20NtDtK2kBgo/TlAoy5YUuhD9/LZ7z7W4j1Fdw2cqD0xEEclf8fxc8xjD6X5Qr+qQQwCEsP8iRiYg==", "dev": true } } @@ -10729,9 +11383,9 @@ "dev": true }, "micromark": { - "version": "2.11.2", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-2.11.2.tgz", - "integrity": "sha512-IXuP76p2uj8uMg4FQc1cRE7lPCLsfAXuEfdjtdO55VRiFO1asrCSQ5g43NmPqFtRwzEnEhafRVzn2jg0UiKArQ==", + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-2.11.4.tgz", + "integrity": "sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==", "dev": true, "requires": { "debug": "^4.0.0", @@ -10811,9 +11465,9 @@ "dev": true }, "mini-css-extract-plugin": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-1.3.3.tgz", - "integrity": "sha512-7lvliDSMiuZc81kI+5/qxvn47SCM7BehXex3f2c6l/pR3Goj58IQxZh9nuPQ3AkGQgoETyXuIqLDaO5Oa0TyBw==", + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-1.3.5.tgz", + "integrity": "sha512-tvmzcwqJJXau4OQE5vT72pRT18o2zF+tQJp8CWchqvfQnTlflkzS+dANYcRdyPRWUWRkfmeNTKltx0NZI/b5dQ==", "dev": true, "requires": { "loader-utils": "^2.0.0", @@ -11101,9 +11755,9 @@ } }, "needle": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/needle/-/needle-2.5.0.tgz", - "integrity": "sha512-o/qITSDR0JCyCKEQ1/1bnUXMmznxabbwi/Y4WwJElf+evwJNFNwIDMCCt5IigFVxgeGBJESLohGtIS9gEzo1fA==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/needle/-/needle-2.6.0.tgz", + "integrity": "sha512-KKYdza4heMsEfSWD7VPUIz3zX2XDwOyX2d+geb4vrERZMT5RMU6ujjaD+I5Yr54uZxQ2w6XRTAhHBbSCyovZBg==", "requires": { "debug": "^3.2.6", "iconv-lite": "^0.4.4", @@ -11331,9 +11985,9 @@ } }, "node-pre-gyp": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.15.0.tgz", - "integrity": "sha512-7QcZa8/fpaU/BKenjcaeFF9hLz2+7S9AqyXFhlH/rilsQ/hPZKK32RtR5EQHJElgu+q5RfbJ34KriI79UWaorA==", + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.16.0.tgz", + "integrity": "sha512-4efGA+X/YXAHLi1hN8KaPrILULaUn2nWecFrn1k2I+99HpoyvcOGEbtcOxpDiUwPF2ZANMJDh32qwOUPenuR1g==", "requires": { "detect-libc": "^1.0.2", "mkdirp": "^0.5.3", @@ -11419,15 +12073,45 @@ } }, "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.0.tgz", + "integrity": "sha512-6lUjEI0d3v6kFrtgA/lOx4zHCWULXsFNIjHolnZCKCTLA6m/G625cdn3O7eNmT0iD3jfo6HZ9cdImGZwf21prw==", "dev": true, "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", + "hosted-git-info": "^3.0.6", + "resolve": "^1.17.0", + "semver": "^7.3.2", "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "is-core-module": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", + "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "dev": true, + "requires": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } + }, + "semver": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } } }, "normalize-path": { @@ -11763,16 +12447,6 @@ "mimic-fn": "^2.1.0" } }, - "open": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/open/-/open-7.3.1.tgz", - "integrity": "sha512-f2wt9DCBKKjlFbjzGb8MOAW8LH8F0mrs1zc7KTjAJ9PZNQbfenzWbNP1VZJvw6ICMG9r14Ah6yfwPn7T7i646A==", - "dev": true, - "requires": { - "is-docker": "^2.0.0", - "is-wsl": "^2.1.1" - } - }, "opn": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", @@ -11795,88 +12469,6 @@ "resolved": "https://registry.npmjs.org/optjs/-/optjs-3.2.2.tgz", "integrity": "sha1-aabOicRCpEQDFBrS+bNwvVu29O4=" }, - "ora": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ora/-/ora-5.2.0.tgz", - "integrity": "sha512-+wG2v8TUU8EgzPHun1k/n45pXquQ9fHnbXVetl9rRgO6kjZszGGbraF3XPTIdgeA+s1lbRjSEftAnyT0w8ZMvQ==", - "dev": true, - "requires": { - "bl": "^4.0.3", - "chalk": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-spinners": "^2.5.0", - "is-interactive": "^1.0.0", - "log-symbols": "^4.0.0", - "strip-ansi": "^6.0.0", - "wcwidth": "^1.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, "original": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz", @@ -11966,9 +12558,9 @@ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" }, "pacote": { - "version": "11.1.14", - "resolved": "https://registry.npmjs.org/pacote/-/pacote-11.1.14.tgz", - "integrity": "sha512-6c5OhQelaJFDfiw/Zd8MfGCvvFHurSdeGzufZMPvRFImdbNOYFciOINf3DtUNUaU3h98eCb749UyHDsgvL19+A==", + "version": "11.2.4", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-11.2.4.tgz", + "integrity": "sha512-GfTeVQGJ6WyBQbQD4t3ocHbyOmTQLmWjkCKSZPmKiGFKYKNUaM5U2gbLzUW8WG1XmS9yQFnsTFA0k3o1+q4klQ==", "dev": true, "requires": { "@npmcli/git": "^2.0.1", @@ -13051,6 +13643,12 @@ "retry": "^0.10.0" }, "dependencies": { + "err-code": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-1.1.2.tgz", + "integrity": "sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA=", + "dev": true + }, "retry": { "version": "0.10.1", "resolved": "https://registry.npmjs.org/retry/-/retry-0.10.1.tgz", @@ -13758,9 +14356,9 @@ } }, "read-package-json-fast": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-1.2.1.tgz", - "integrity": "sha512-OFbpwnHcv74Oa5YN5WvbOBfLw6yPmPcwvyJJw/tj9cWFBF7juQUDLDSZiOjEcgzfweWeeROOmbPpNN1qm4hcRg==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-1.2.2.tgz", + "integrity": "sha512-39DbPJjkltEzfXJXB6D8/Ir3GFOU2YbSKa2HaB/Y3nKrc/zY+0XrALpID6/13ezWyzqvOHrBbR4t4cjQuTdBVQ==", "dev": true, "requires": { "json-parse-even-better-errors": "^2.3.0", @@ -13779,6 +14377,24 @@ "type-fest": "^0.6.0" }, "dependencies": { + "hosted-git-info": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", + "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "dev": true + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, "type-fest": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", @@ -13833,18 +14449,6 @@ "util-deprecate": "^1.0.1" } }, - "readdir-scoped-modules": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz", - "integrity": "sha512-asaikDeqAQg7JifRsZn1NJZXo9E+VwlyCfbkZhwyISinqk5zNS6266HS5kah6P0SaQKGF6SkNnZVHUzHFYxYDw==", - "dev": true, - "requires": { - "debuglog": "^1.0.1", - "dezalgo": "^1.0.0", - "graceful-fs": "^4.1.2", - "once": "^1.3.0" - } - }, "readdirp": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", @@ -14292,12 +14896,21 @@ } }, "rollup": { - "version": "2.36.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.36.1.tgz", - "integrity": "sha512-eAfqho8dyzuVvrGqpR0ITgEdq0zG2QJeWYh+HeuTbpcaXk8vNFc48B7bJa1xYosTCKx0CuW+447oQOW8HgBIZQ==", + "version": "2.38.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.38.4.tgz", + "integrity": "sha512-B0LcJhjiwKkTl79aGVF/u5KdzsH8IylVfV56Ut6c9ouWLJcUK17T83aZBetNYSnZtXf2OHD4+2PbmRW+Fp5ulg==", "dev": true, "requires": { - "fsevents": "~2.1.2" + "fsevents": "~2.3.1" + }, + "dependencies": { + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + } } }, "run-async": { @@ -14356,9 +14969,9 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "sass": { - "version": "1.32.4", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.32.4.tgz", - "integrity": "sha512-N0BT0PI/t3+gD8jKa83zJJUb7ssfQnRRfqN+GIErokW6U4guBpfYl8qYB+OFLEho+QvnV5ZH1R9qhUC/Z2Ch9w==", + "version": "1.32.6", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.32.6.tgz", + "integrity": "sha512-1bcDHDcSqeFtMr0JXI3xc/CXX6c4p0wHHivJdru8W7waM7a1WjKMm4m/Z5sY7CbVw4Whi2Chpcw6DFfSWwGLzQ==", "dev": true, "requires": { "chokidar": ">=2.0.0 <4.0.0" @@ -14933,9 +15546,9 @@ } }, "socket.io": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-3.1.0.tgz", - "integrity": "sha512-Aqg2dlRh6xSJvRYK31ksG65q4kmBOqU4g+1ukhPcoT6wNGYoIwSYPlCPuRwOO9pgLUajojGFztl6+V2opmKcww==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-3.1.1.tgz", + "integrity": "sha512-7cBWdsDC7bbyEF6WbBqffjizc/H4YF1wLdZoOzuYfo2uMNSFjJKuQ36t0H40o9B20DO6p+mSytEd92oP4S15bA==", "dev": true, "requires": { "@types/cookie": "^0.4.0", @@ -15143,9 +15756,9 @@ } }, "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", + "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", "dev": true }, "sourcemap-codec": { @@ -15155,9 +15768,9 @@ "dev": true }, "spdx-correct": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", - "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", "dev": true, "requires": { "spdx-expression-parse": "^3.0.0", @@ -15165,15 +15778,15 @@ } }, "spdx-exceptions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", - "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", "dev": true }, "spdx-expression-parse": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", - "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "dev": true, "requires": { "spdx-exceptions": "^2.1.0", @@ -15181,9 +15794,9 @@ } }, "spdx-license-ids": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", - "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz", + "integrity": "sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==", "dev": true }, "spdy": { @@ -15242,12 +15855,63 @@ "dev": true }, "speed-measure-webpack-plugin": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/speed-measure-webpack-plugin/-/speed-measure-webpack-plugin-1.3.3.tgz", - "integrity": "sha512-2ljD4Ch/rz2zG3HsLsnPfp23osuPBS0qPuz9sGpkNXTN1Ic4M+W9xB8l8rS8ob2cO4b1L+WTJw/0AJwWYVgcxQ==", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/speed-measure-webpack-plugin/-/speed-measure-webpack-plugin-1.4.2.tgz", + "integrity": "sha512-AtVzD0bnIy2/B0fWqJpJgmhcrfWFhBlduzSo0uwplr/QvB33ZNZj2NEth3NONgdnZJqicK0W0mSxnLSbsVCDbw==", "dev": true, "requires": { - "chalk": "^2.0.1" + "chalk": "^4.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "split-string": { @@ -15599,9 +16263,9 @@ } }, "stylelint": { - "version": "13.9.0", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-13.9.0.tgz", - "integrity": "sha512-VVWH2oixOAxpWL1vH+V42ReCzBjW2AeqskSAbi8+3OjV1Xg3VZkmTcAqBZfRRvJeF4BvYuDLXebW3tIHxgZDEg==", + "version": "13.10.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-13.10.0.tgz", + "integrity": "sha512-eDuLrL0wzPKbl5/TbNGZcbw0lTIGbDEr5W6lCODvb1gAg0ncbgCRt7oU0C2VFDvbrcY0A3MFZOwltwTRmc0XCw==", "dev": true, "requires": { "@stylelint/postcss-css-in-js": "^0.37.2", @@ -15623,7 +16287,7 @@ "ignore": "^5.1.8", "import-lazy": "^4.0.0", "imurmurhash": "^0.1.4", - "known-css-properties": "^0.20.0", + "known-css-properties": "^0.21.0", "lodash": "^4.17.20", "log-symbols": "^4.0.0", "mathml-tag-names": "^2.1.3", @@ -15669,12 +16333,6 @@ "color-convert": "^2.0.1" } }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - }, "chalk": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", @@ -15709,34 +16367,6 @@ "ms": "2.1.2" } }, - "fast-glob": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz", - "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.0", - "merge2": "^1.3.0", - "micromatch": "^4.0.2", - "picomatch": "^2.2.1" - } - }, - "globby": { - "version": "11.0.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.2.tgz", - "integrity": "sha512-2ZThXDvvV8fYFRVIxnrMQBipZQDr7MxKAmQK1vujaj9/7eF0efG7BPUKJ7jP7G5SLF37xKDXvO4S/KKLj/Z0og==", - "dev": true, - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" - } - }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -15876,9 +16506,9 @@ } }, "stylelint-scss": { - "version": "3.18.0", - "resolved": "https://registry.npmjs.org/stylelint-scss/-/stylelint-scss-3.18.0.tgz", - "integrity": "sha512-LD7+hv/6/ApNGt7+nR/50ft7cezKP2HM5rI8avIdGaUWre3xlHfV4jKO/DRZhscfuN+Ewy9FMhcTq0CcS0C/SA==", + "version": "3.19.0", + "resolved": "https://registry.npmjs.org/stylelint-scss/-/stylelint-scss-3.19.0.tgz", + "integrity": "sha512-Ic5bsmpS4wVucOw44doC1Yi9f5qbeVL4wPFiEOaUElgsOuLEN6Ofn/krKI8BeNL2gAn53Zu+IcVV4E345r6rBw==", "dev": true, "requires": { "lodash": "^4.17.15", @@ -15886,25 +16516,6 @@ "postcss-resolve-nested-selector": "^0.1.1", "postcss-selector-parser": "^6.0.2", "postcss-value-parser": "^4.1.0" - }, - "dependencies": { - "postcss-selector-parser": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz", - "integrity": "sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg==", - "dev": true, - "requires": { - "cssesc": "^3.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - }, - "postcss-value-parser": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", - "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==", - "dev": true - } } }, "stylus": { @@ -15959,9 +16570,9 @@ } }, "stylus-loader": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/stylus-loader/-/stylus-loader-4.3.2.tgz", - "integrity": "sha512-xXVKHY+J7GBlOmqjCL1VvQfc+pFkBdWGtcpJSvBGE49nWWHaukox7KCjRdLTEzjrmHODm4+rLpqkYWzfJteMXQ==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/stylus-loader/-/stylus-loader-4.3.3.tgz", + "integrity": "sha512-PpWB5PnCXUzW4WMYhCvNzAHJBjIBPMXwsdfkkKuA9W7k8OQFMl/19/AQvaWsxz2IptxUlCseyJ6TY/eEKJ4+UQ==", "dev": true, "requires": { "fast-glob": "^3.2.4", @@ -16060,9 +16671,9 @@ }, "dependencies": { "ajv": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-7.0.3.tgz", - "integrity": "sha512-R50QRlXSxqXcQP5SvKUrw8VZeypvo12i2IX0EeR5PiZ7bEKeHWgzgo264LDadUsCU42lTJVhFikTqJwNeH34gQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-7.1.0.tgz", + "integrity": "sha512-svS9uILze/cXbH0z2myCK2Brqprx/+JJYK5pHicT/GQiBfzzhUVAIT6MwqJg8y4xV/zoGsUeuPuwtoiKSGE15g==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -16556,15 +17167,15 @@ } }, "typescript": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.5.tgz", - "integrity": "sha512-ywmr/VrTVCmNTJ6iV2LwIrfG1P+lv6luD8sUJs+2eI9NLGigaN+nUQc13iHqisq7bra9lnmUSYqbJvegraBOPQ==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.7.tgz", + "integrity": "sha512-yi7M4y74SWvYbnazbn8/bmJmX4Zlej39ZOqwG/8dut/MYoSQ119GY9ZFbbGsD4PFZYWxqik/XsP3vk3+W5H3og==", "dev": true }, "ua-parser-js": { - "version": "0.7.23", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.23.tgz", - "integrity": "sha512-m4hvMLxgGHXG3O3fQVAyyAQpZzDOvwnhOTjYz5Xmr7r/+LpkNy3vJXdVRWgd1TkAb7NGROZuSy96CrlNVjA7KA==", + "version": "0.7.24", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.24.tgz", + "integrity": "sha512-yo+miGzQx5gakzVK3QFfN0/L9uVhosXBBO7qmnk7c2iw1IhL212wfA3zbnI54B0obGwC/5NWub/iT9sReMx+Fw==", "dev": true }, "unicode-canonical-property-names-ecmascript": { @@ -17667,9 +18278,9 @@ } }, "webpack-dev-server": { - "version": "3.11.1", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.11.1.tgz", - "integrity": "sha512-u4R3mRzZkbxQVa+MBWi2uVpB5W59H3ekZAJsQlKUTdl7Elcah2EhygTPLmeFXybQkf9i2+L0kn7ik9SnXa6ihQ==", + "version": "3.11.2", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.11.2.tgz", + "integrity": "sha512-A80BkuHRQfCiNtGBS1EMf2ChTUs0x+B3wGDFmOeT4rmJOHhHTCH2naNxIHhmkr0/UillP4U3yeIyv1pNp+QDLQ==", "dev": true, "requires": { "ansi-html": "0.0.7", @@ -18289,9 +18900,9 @@ "dev": true }, "y18n": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", + "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==" }, "yallist": { "version": "4.0.0", diff --git a/console/package.json b/console/package.json index 042903a45..31e162618 100644 --- a/console/package.json +++ b/console/package.json @@ -33,7 +33,7 @@ "file-saver": "^2.0.5", "google-proto-files": "^2.4.0", "google-protobuf": "^3.13.0", - "grpc": "^1.24.3", + "grpc": "^1.24.5", "grpc-web": "^1.2.1", "moment": "^2.29.1", "ngx-quicklink": "^0.2.6", @@ -44,28 +44,28 @@ "zone.js": "~0.11.3" }, "devDependencies": { - "@angular/cli": "~11.1.2", - "@angular-devkit/build-angular": "~0.1101.2", + "@angular/cli": "~11.2.0", + "@angular-devkit/build-angular": "~0.1102.0", "@angular/compiler-cli": "~11.0.0", "@types/jasmine": "~3.6.3", - "@angular/language-service": "~11.1.1", + "@angular/language-service": "~11.2.0", "@types/jasminewd2": "~2.0.3", - "@types/node": "^14.14.22", + "@types/node": "^14.14.28", "codelyzer": "^6.0.0", "jasmine-core": "~3.6.0", "jasmine-spec-reporter": "~6.0.0", - "karma": "~6.0.3", + "karma": "~6.1.1", "karma-chrome-launcher": "~3.1.0", "karma-coverage-istanbul-reporter": "~3.0.2", "karma-jasmine": "~4.0.0", "karma-jasmine-html-reporter": "^1.5.0", "prettier": "^2.2.1", "protractor": "~7.0.0", - "stylelint": "^13.9.0", + "stylelint": "^13.10.0", "stylelint-config-standard": "^20.0.0", - "stylelint-scss": "^3.18.0", + "stylelint-scss": "^3.19.0", "ts-node": "~9.1.1", "tslint": "~6.1.3", - "typescript": "^4.0.5" + "typescript": "^4.0.7" } } diff --git a/console/src/app/app-routing.module.ts b/console/src/app/app-routing.module.ts index 4947ee464..2db6941e5 100644 --- a/console/src/app/app-routing.module.ts +++ b/console/src/app/app-routing.module.ts @@ -11,6 +11,15 @@ const routes: Routes = [ loadChildren: () => import('./pages/home/home.module').then(m => m.HomeModule), canActivate: [AuthGuard], }, + { + path: 'firststeps', + loadChildren: () => import('./modules/onboarding/onboarding.module') + .then(m => m.OnboardingModule), + canActivate: [AuthGuard, RoleGuard], + data: { + roles: ['iam.write'], + } + }, { path: 'granted-projects', loadChildren: () => import('./pages/projects/granted-projects/granted-projects.module') diff --git a/console/src/app/app.component.html b/console/src/app/app.component.html index dd61103f6..d6178a4a9 100644 --- a/console/src/app/app.component.html +++ b/console/src/app/app.component.html @@ -1,19 +1,25 @@ - - + + src="../assets/images/zitadel-logo-solo-light.svg" /> - + - @@ -37,8 +43,8 @@ - + diff --git a/console/src/app/modules/card/card.component.scss b/console/src/app/modules/card/card.component.scss index 273957e64..6654a3925 100644 --- a/console/src/app/modules/card/card.component.scss +++ b/console/src/app/modules/card/card.component.scss @@ -24,6 +24,8 @@ font-size: 16px; text-transform: uppercase; letter-spacing: .05em; + text-overflow: ellipsis; + overflow: hidden; } .fill-space { diff --git a/console/src/app/modules/card/card.component.ts b/console/src/app/modules/card/card.component.ts index 9fd2a15c8..98b4a65e2 100644 --- a/console/src/app/modules/card/card.component.ts +++ b/console/src/app/modules/card/card.component.ts @@ -18,7 +18,7 @@ import { Component, Input } from '@angular/core'; ], }) export class CardComponent { - public expanded: boolean = true; + @Input() public expanded: boolean = true; @Input() public title: string = ''; @Input() public description: string = ''; @Input() public animate: boolean = false; diff --git a/console/src/app/modules/idp-create/idp-create.component.ts b/console/src/app/modules/idp-create/idp-create.component.ts index 223aee16c..4cd6bf230 100644 --- a/console/src/app/modules/idp-create/idp-create.component.ts +++ b/console/src/app/modules/idp-create/idp-create.component.ts @@ -110,9 +110,9 @@ export class IdpCreateComponent implements OnInit, OnDestroy { setTimeout(() => { this.loading = false; this.router.navigate([ - this.serviceType === PolicyComponentServiceType.MGMT ? 'org' : - this.serviceType === PolicyComponentServiceType.ADMIN ? 'iam' : '', - 'idp', idp.getId()]); + (this.serviceType === PolicyComponentServiceType.MGMT ? 'org' : + this.serviceType === PolicyComponentServiceType.ADMIN ? 'iam' : ''), + 'policy', 'login']); }, 2000); }).catch(error => { this.toast.showError(error); diff --git a/console/src/app/modules/idp-table/idp-table.component.html b/console/src/app/modules/idp-table/idp-table.component.html index 510c8f452..2e9cb0629 100644 --- a/console/src/app/modules/idp-table/idp-table.component.html +++ b/console/src/app/modules/idp-table/idp-table.component.html @@ -1,6 +1,6 @@ - +
diff --git a/console/src/app/modules/info-section/info-section.component.html b/console/src/app/modules/info-section/info-section.component.html index 90564546d..0ca31edc2 100644 --- a/console/src/app/modules/info-section/info-section.component.html +++ b/console/src/app/modules/info-section/info-section.component.html @@ -1,5 +1,7 @@ -
- +
+ + +
diff --git a/console/src/app/modules/info-section/info-section.component.scss b/console/src/app/modules/info-section/info-section.component.scss index ee7501994..0bc8c21f3 100644 --- a/console/src/app/modules/info-section/info-section.component.scss +++ b/console/src/app/modules/info-section/info-section.component.scss @@ -7,24 +7,36 @@ .info-section-row { display: flex; - background-color: if($is-dark-theme, #ffffff13, #f3f3f3); border-radius: 4px; padding: .5rem 0; padding-right: 1rem; - color: if($is-dark-theme, #d6d6d6, #3c4257); font-size: 14px; .icon { - margin-right: 1rem; - height: 1.2rem; - line-height: 1.2rem; - font-size: 1.2rem; - margin-left: .5rem; - color: $primary-color; + margin-right: 1rem; + height: 1.2rem; + line-height: 1.2rem; + font-size: 1.2rem; + margin-left: .5rem; } + .info-section-content { - flex: 1; + flex: 1; + } + + &.info { + background-color: if($is-dark-theme, #4f566b, #cbf4c9); + color: if($is-dark-theme, #cbf4c9, #0e6245); + + .icon { + color: $primary-color; + } + } + + &.warn { + background-color: if($is-dark-theme, #4f566b, #ffc1c1); + color: if($is-dark-theme, #ffc1c1, #620e0e); } } } diff --git a/console/src/app/modules/info-section/info-section.component.ts b/console/src/app/modules/info-section/info-section.component.ts index 999364e46..c6c093648 100644 --- a/console/src/app/modules/info-section/info-section.component.ts +++ b/console/src/app/modules/info-section/info-section.component.ts @@ -1,8 +1,16 @@ -import { Component } from '@angular/core'; +import { Component, Input } from '@angular/core'; + +enum InfoSectionType { + INFO = 'INFO', + WARN = 'WARN', +} @Component({ selector: 'cnsl-info-section', templateUrl: './info-section.component.html', styleUrls: ['./info-section.component.scss'], }) -export class InfoSectionComponent { } +export class InfoSectionComponent { + + @Input() type = InfoSectionType.INFO; +} diff --git a/console/src/app/modules/onboarding/onboarding-routing.module.ts b/console/src/app/modules/onboarding/onboarding-routing.module.ts new file mode 100644 index 000000000..459446304 --- /dev/null +++ b/console/src/app/modules/onboarding/onboarding-routing.module.ts @@ -0,0 +1,18 @@ +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; + +import { OnboardingComponent } from './onboarding.component'; + +const routes: Routes = [ + { + path: '', + component: OnboardingComponent, + data: { animation: 'AddPage' }, + }, +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule], +}) +export class OnboardingRoutingModule { } diff --git a/console/src/app/modules/onboarding/onboarding.component.html b/console/src/app/modules/onboarding/onboarding.component.html new file mode 100644 index 000000000..e11a82996 --- /dev/null +++ b/console/src/app/modules/onboarding/onboarding.component.html @@ -0,0 +1,27 @@ +
+
+

{{'ONBOARDING.HEADER' | translate}}

+

{{'ONBOARDING.TITLE' | translate}}

+
+
+

{{'ONBOARDING.DESCRIPTION' | translate}}

+ +

{{'ONBOARDING.STEPS_TITLE' | translate}}

+
+ +
+

{{step.titleI18nKey | translate}}

+

{{step.descI18nKey | translate}}

+
+ + +
+
+
\ No newline at end of file diff --git a/console/src/app/modules/onboarding/onboarding.component.scss b/console/src/app/modules/onboarding/onboarding.component.scss new file mode 100644 index 000000000..d58ff345d --- /dev/null +++ b/console/src/app/modules/onboarding/onboarding.component.scss @@ -0,0 +1,147 @@ +@import '~@angular/material/theming'; + +@mixin onboarding-theme($theme) { + /* stylelint-disable */ + $primary: map-get($theme, primary); + $primary-color: mat-color($primary, 500); + $is-dark-theme: map-get($theme, is-dark); + /* stylelint-enable */ + + .onboarding-row { + box-shadow: inset 0 -1px if($is-dark-theme, #303131, #e3e8ee); + + .prev { + background: $primary-color; + } + + .goto { + text-decoration: none; + background: white; + border: 1px solid if($is-dark-theme, #303131, #e3e8ee); + + &.docs { + background-color: $primary-color; + + i { + font-size: 1rem; + margin-left: 3px; + } + } + } + } +} + +.split { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + display: flex; + flex-direction: column; + box-sizing: border-box; + border-radius: 0.5rem; + box-shadow: 0 3px 8px 0 rgb(0 0 0 / 6%); + + @media only screen and (min-width: 1024px) { + flex-direction: row; + + .right { + overflow: auto; + } + } + + .left { + flex-basis: 300px; + box-sizing: border-box; + padding: 1.5rem; + background: linear-gradient(40deg, rgb(80, 66, 121),rgb(177, 59, 122),rgb(225,53,81), rgb(230,107,86)); + box-shadow: inset -2px 1px 15px -9px #000000; + + h1 { + color: white; + } + + .firststeps { + color: #fad6e3; + text-transform: uppercase; + font-size: 12px; + font-weight: bold; + } + + p { + color: #fad6e3; + font-size: 12px; + font-weight: bold; + } + + button { + width: 100%; + } + } + + .right { + padding: 1.5rem; + flex: 1; + box-sizing: border-box; + + .desc { + color: var(--grey); + font-size: 20px; + margin-top: .5rem; + } + + .onboarding-row { + display: flex; + padding: 1rem 0; + align-items: center; + + .prev { + height: 40px; + width: 40px; + min-width: 40px; + border-radius: .5rem; + display: flex; + align-items: center; + justify-content: center; + margin-right: 2rem; + color: white; + font-size: 1.2rem; + box-shadow: 0 3px 8px 0 rgb(0 0 0 / 6%); + } + + h3 { + margin-top: 0; + margin-bottom: .5rem; + font-size: 15px; + } + + p { + font-size: 12px; + margin: 0; + color: var(--grey); + } + + .fill-space { + flex: 1; + } + + .action-row { + display: flex; + align-items: center; + flex-wrap: wrap; + justify-content: flex-end; + + .goto { + background-color: white; + padding: 2px 1rem; + color: black; + border-radius: 50vw; + font-size: 12px; + margin: .5rem 0 .5rem 1rem; + white-space: nowrap; + } + } + } + } +} \ No newline at end of file diff --git a/console/src/app/modules/onboarding/onboarding.component.spec.ts b/console/src/app/modules/onboarding/onboarding.component.spec.ts new file mode 100644 index 000000000..9361e6bb3 --- /dev/null +++ b/console/src/app/modules/onboarding/onboarding.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { OnboardingComponent } from './onboarding.component'; + +describe('OnboardingComponent', () => { + let component: OnboardingComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ OnboardingComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(OnboardingComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/console/src/app/modules/onboarding/onboarding.component.ts b/console/src/app/modules/onboarding/onboarding.component.ts new file mode 100644 index 000000000..3091e9429 --- /dev/null +++ b/console/src/app/modules/onboarding/onboarding.component.ts @@ -0,0 +1,16 @@ +import { Component, OnInit } from '@angular/core'; +import { AuthenticationService } from 'src/app/services/authentication.service'; + +@Component({ + selector: 'cnsl-onboarding', + templateUrl: './onboarding.component.html', + styleUrls: ['./onboarding.component.scss'] +}) +export class OnboardingComponent { + public steps = [ + { titleI18nKey: 'ONBOARDING.STEPS.1.TITLE', descI18nKey: 'ONBOARDING.STEPS.1.DESC', docs: "https://docs.zitadel.ch/use", link: ['/projects', 'create'] }, + { titleI18nKey: 'ONBOARDING.STEPS.2.TITLE', descI18nKey: 'ONBOARDING.STEPS.2.DESC', docs: "https://docs.zitadel.ch/use", link: ['/projects'] }, + { titleI18nKey: 'ONBOARDING.STEPS.3.TITLE', descI18nKey: 'ONBOARDING.STEPS.3.DESC', link: ['/iam', 'policies'] }, + ]; + constructor() { } +} diff --git a/console/src/app/modules/onboarding/onboarding.module.ts b/console/src/app/modules/onboarding/onboarding.module.ts new file mode 100644 index 000000000..2ba9318ca --- /dev/null +++ b/console/src/app/modules/onboarding/onboarding.module.ts @@ -0,0 +1,18 @@ +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { TranslateModule } from '@ngx-translate/core'; + +import { OnboardingRoutingModule } from './onboarding-routing.module'; +import { OnboardingComponent } from './onboarding.component'; + +@NgModule({ + declarations: [OnboardingComponent], + imports: [ + CommonModule, + TranslateModule, + OnboardingRoutingModule, + MatButtonModule, + ], +}) +export class OnboardingModule { } diff --git a/console/src/app/modules/policies/login-policy/login-policy.component.html b/console/src/app/modules/policies/login-policy/login-policy.component.html index e88404bf3..930f2f869 100644 --- a/console/src/app/modules/policies/login-policy/login-policy.component.html +++ b/console/src/app/modules/policies/login-policy/login-policy.component.html @@ -73,14 +73,14 @@

{{ 'MFA.LIST.MULTIFACTORDESCRIPTION' | translate }}

+ [disabled]="([serviceType == PolicyComponentServiceType.ADMIN ? 'iam.policy.write' : serviceType == PolicyComponentServiceType.MGMT ? 'policy.write' : ''] | hasRole | async) == false">

{{ 'MFA.LIST.SECONDFACTORTITLE' | translate }}

{{ 'MFA.LIST.SECONDFACTORDESCRIPTION' | translate }}

+ [disabled]="([serviceType == PolicyComponentServiceType.ADMIN ? 'iam.policy.write' : serviceType == PolicyComponentServiceType.MGMT ? 'policy.write' : ''] | hasRole | async) == false"> diff --git a/console/src/app/pages/home/home.component.html b/console/src/app/pages/home/home.component.html index dd89e0074..5aba76393 100644 --- a/console/src/app/pages/home/home.component.html +++ b/console/src/app/pages/home/home.component.html @@ -16,12 +16,42 @@
+ + +

{{'ONBOARDING.HEADER' | translate}}

+

{{'ONBOARDING.TITLE' | translate}}

+

{{'ONBOARDING.DESCRIPTION' | translate}}

+ +
+
+ + +

{{'HOME.QUICKSTARTS.LABEL' | translate}}

+

{{'HOME.QUICKSTARTS.TITLE' | translate}}

+

{{'HOME.QUICKSTARTS.DESCRIPTION' | translate}}

+
+ + + + +
+ +
+

- {{'HOME.IAM'| translate}}

+ {{'HOME.IAM'| translate}} +

{{'HOME.IAM_DESC'| translate}}

@@ -30,15 +60,12 @@ class="las la-link">
- {{'HOME.IAM_POLICY_IAM' | translate}} - {{'HOME.IAM_POLICY_COMPLEXITY' | translate}} - {{'HOME.IAM_POLICY_LOGIN' | translate}} + {{'HOME.IAM_POLICY_IAM' | + translate}} + {{'HOME.IAM_POLICY_COMPLEXITY' + | translate}} + {{'HOME.IAM_POLICY_LOGIN' | + translate}} @@ -59,8 +86,8 @@ @@ -69,18 +96,18 @@

- {{'HOME.PROJECTS'| translate}}

+ {{'HOME.PROJECTS'| translate}} +

{{'HOME.PROJECTS_DESC'| translate}}

- {{'HOME.PROJECTS_NEW_LINK' | translate}} + {{'HOME.PROJECTS_NEW_LINK' | + translate}}
@@ -92,23 +119,21 @@ {{'HOME.PROTECTION'| translate}}

{{'HOME.PROTECTION_DESC'| translate}}

- {{'HOME.ORG_POLICY_IAM' | translate}} + {{'HOME.ORG_POLICY_IAM' | + translate}} {{'HOME.ORG_POLICY_COMPLEXITY' | translate}} - {{'HOME.ORG_POLICY_LOGIN' | translate}} + [routerLink]="[ '/org', 'policy','complexity']">{{'HOME.ORG_POLICY_COMPLEXITY' | + translate}} + {{'HOME.ORG_POLICY_LOGIN' | + translate}}
@@ -118,15 +143,14 @@

- {{'HOME.USERS'| translate}}

+ {{'HOME.USERS'| translate}} +

{{'HOME.USERS_DESC'| translate}}

- {{'HOME.USERS_HUMANS' | translate}} - {{'HOME.USERS_MACHINES' | translate}} + {{'HOME.USERS_HUMANS' | + translate}} + {{'HOME.USERS_MACHINES' | + translate}} {{'HOME.USERS_CREATE' | translate}} diff --git a/console/src/app/pages/home/home.component.scss b/console/src/app/pages/home/home.component.scss index af6a5c076..091d2f1ea 100644 --- a/console/src/app/pages/home/home.component.scss +++ b/console/src/app/pages/home/home.component.scss @@ -1,6 +1,7 @@ .wrapper { padding-bottom: 100px; + position: relative; .header { display: flex; @@ -31,6 +32,78 @@ margin: -1rem; justify-content: space-evenly; + .onboard, + .quickstart { + text-decoration: none; + cursor: pointer; + box-sizing: border-box; + flex: 1 0 45%; + position: relative; + border-radius: 0.5rem; + margin: 1rem; + padding: 1.5rem; + box-shadow: 0 3px 8px 0 rgb(0 0 0 / 6%); + + h2 { + color: white; + } + + .first-steps { + text-transform: uppercase; + font-size: 12px; + font-weight: bold; + } + + .close { + visibility: hidden; + position: absolute; + top: 0; + right: 0; + + i { + color: white; + font-size: 1rem; + } + } + + &:hover { + .close { + visibility: visible; + } + } + } + + .onboard { + background: linear-gradient(40deg, rgb(80, 66, 121),rgb(177, 59, 122),rgb(225,53,81), rgb(230,107,86)); + + p { + color: #fad6e3; + } + } + + .quickstart { + background: linear-gradient(30deg, #2283a6,#6c8f59); + + p { + color: #d6f3fa; + } + + .logo-cloud { + display: flex; + flex-wrap: wrap; + margin: -0.5rem; + + i { + font-size: 40px; + padding: .5rem; + border: 1px solid #ffffff50; + border-radius: .5rem; + margin: 0.5rem; + color: white; + } + } + } + .item { flex: 1 0 45%; margin: 0 1rem; diff --git a/console/src/app/pages/home/home.component.ts b/console/src/app/pages/home/home.component.ts index 71a65d38c..e9cbc25f4 100644 --- a/console/src/app/pages/home/home.component.ts +++ b/console/src/app/pages/home/home.component.ts @@ -8,8 +8,26 @@ import { GrpcAuthService } from 'src/app/services/grpc-auth.service'; }) export class HomeComponent { public dark: boolean = true; + public firstStepsDismissed: boolean = false; + public quickstartsDismissed: boolean = false; + constructor(public authService: GrpcAuthService) { const theme = localStorage.getItem('theme'); this.dark = theme === 'dark-theme' ? true : theme === 'light-theme' ? false : true; + + this.firstStepsDismissed = localStorage.getItem('firstStartDismissed') == 'true' ? true : false; + this.quickstartsDismissed = localStorage.getItem('quickstartsDismissed') == 'true' ? true : false; + } + + dismissFirstSteps(event: Event): void { + event.preventDefault(); + localStorage.setItem('firstStartDismissed', 'true'); + this.firstStepsDismissed = true; + } + + dismissQuickstarts(event: Event): void { + event.preventDefault(); + localStorage.setItem('quickstartsDismissed', 'true'); + this.firstStepsDismissed = true; } } diff --git a/console/src/app/pages/home/home.module.ts b/console/src/app/pages/home/home.module.ts index 2d397bd3f..535d247a1 100644 --- a/console/src/app/pages/home/home.module.ts +++ b/console/src/app/pages/home/home.module.ts @@ -1,19 +1,20 @@ import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; +import { MatRippleModule } from '@angular/material/core'; import { MatIconModule } from '@angular/material/icon'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { MatTooltipModule } from '@angular/material/tooltip'; import { TranslateModule } from '@ngx-translate/core'; import { HasRoleModule } from 'src/app/directives/has-role/has-role.module'; import { AvatarModule } from 'src/app/modules/avatar/avatar.module'; import { CardModule } from 'src/app/modules/card/card.module'; +import { OnboardingModule } from 'src/app/modules/onboarding/onboarding.module'; import { SharedModule } from 'src/app/modules/shared/shared.module'; import { HomeRoutingModule } from './home-routing.module'; import { HomeComponent } from './home.component'; - - @NgModule({ declarations: [HomeComponent], imports: [ @@ -24,9 +25,12 @@ import { HomeComponent } from './home.component'; MatButtonModule, TranslateModule, AvatarModule, + MatTooltipModule, SharedModule, MatProgressSpinnerModule, CardModule, + MatRippleModule, + OnboardingModule, ], }) export class HomeModule { } diff --git a/console/src/app/pages/projects/apps/app-create/app-create.component.html b/console/src/app/pages/projects/apps/app-create/app-create.component.html index c43900be6..567e85ddb 100644 --- a/console/src/app/pages/projects/apps/app-create/app-create.component.html +++ b/console/src/app/pages/projects/apps/app-create/app-create.component.html @@ -23,18 +23,14 @@

{{'APP.OIDC.TITLEFIRST' | translate}}

{{ 'APP.NAME' | translate }} - + {{'PROJECT.APP.NAMEREQUIRED' | translate}}

{{'APP.OIDC.TYPETITLE' | translate}}

- - -
{{('APP.OIDC.APPTYPE'+type.key.toString()) | translate}}
-
-
+ +
@@ -42,37 +38,19 @@ - - {{'APP.OIDC.RESPONSESECTION' | translate}} -
- - {{'APP.OIDC.RESPONSE'+responsetype.type | translate}} - -
-
- - -
-
- - +
{{'APP.OIDC.AUTHMETHODSECTION' | translate}} - - - {{'APP.OIDC.AUTHMETHOD'+authmethod.type | translate}} - - + + +
- +
@@ -89,25 +67,10 @@

{{'APP.OIDC.REDIRECTDESCRIPTIONWEB' | translate}}

- - - {{ 'APP.OIDC.REDIRECT' | translate }} - - - - - - - {{uri}} cancel - - - -

{{'APP.OIDC.REDIRECTNOTVALID' | translate}}

+ +

{{'APP.OIDC.POSTREDIRECTTITLE' | translate}}

{{'APP.OIDC.REDIRECTDESCRIPTIONWEB' | translate}}

-
- - {{ 'APP.OIDC.POSTLOGOUTREDIRECT' | translate }} - - - - - - - {{uri}} cancel - - - -

{{'APP.OIDC.REDIRECTNOTVALID' | translate}}

+ +
@@ -171,9 +118,8 @@ [ {{'APP.OIDC.GRANT'+element | translate}} - {{i < oidcApp.grantTypesList.length - 1 ? ', ': ''}} - ] - + {{i < oidcApp.grantTypesList.length - 1 ? ', ' : '' }} ] +
@@ -182,9 +128,8 @@ [ {{('APP.OIDC.RESPONSE'+element | translate)}} - {{i < oidcApp.responseTypesList.length - 1 ? ', ': ''}} - ] - + {{i < oidcApp.responseTypesList.length - 1 ? ', ' : '' }} ] +
@@ -205,9 +150,8 @@ [ {{redirect}} - {{i < oidcApp.redirectUrisList.length - 1 ? ', ': ''}} - ] - + {{i < oidcApp.redirectUrisList.length - 1 ? ', ' : '' }} ] +
@@ -217,15 +161,14 @@ [ {{redirect}} - {{i < oidcApp.postLogoutRedirectUrisList.length - 1 ? ', ': ''}} - ] - + {{i < oidcApp.postLogoutRedirectUrisList.length - 1 ? ', ' : '' }} ] +
- +
@@ -241,8 +184,8 @@ {{ 'APP.OIDC.APPTYPE' | translate }} - - {{ 'APP.OIDC.APPTYPE'+type | translate }} + + {{ 'APP.OIDC.APPTYPE'+type.type | translate }} @@ -274,32 +217,18 @@ - - {{ 'APP.OIDC.REDIRECT' | translate }} - - - {{uri}} cancel - - - - - - - {{ 'APP.OIDC.POSTLOGOUTREDIRECT' | translate }} - - - {{uri}} cancel - - - - +
+ + + + +
+ + + + + + +

{{ 'APP.PAGES.DESCRIPTION' | translate }}

{{'PROJECT.PAGES.ZITADELPROJECT' | translate}}

@@ -12,52 +34,85 @@ {{errorMessage}} - -
-
- - - {{'APP.PAGES.DETAIL.STATE.'+AppState.APPSTATE_INACTIVE | translate}} - - - {{'APP.PAGES.DETAIL.STATE.'+AppState.APPSTATE_ACTIVE | translate}} - - + +
+ + + {{'APP.PAGES.DETAIL.STATE.'+AppState.APPSTATE_INACTIVE | translate}} + + + {{'APP.PAGES.DETAIL.STATE.'+AppState.APPSTATE_ACTIVE | translate}} + + - - {{ 'APP.NAME' | translate }} - - - - -

Discovery Endpoint: {{docs.discoveryEndpoint}}

-

Issuer: {{docs.issuer}}

-
-
-
- -
- - - - -
- + + {{ 'APP.NAME' | translate }} + +
+ + + + +
+ +
    +
  • + {{problem.localizedMessage}}
  • +
+
+
+ +
+

{{'APP.OIDC.REDIRECTSECTIONTITLE' | translate}}

+ + + {{ 'APP.OIDC.DEVMODE' | translate }} + + + + {{'APP.OIDC.REDIRECTDESCRIPTIONNATIVE' | translate}} + + +

+ {{'APP.OIDC.REDIRECTDESCRIPTIONWEB' | translate}}

+ +
+ + + + + + +
+ + + + +
+ +
+ +
-
- -
    -
  • - {{problem.localizedMessage}}
  • -
-
-
-
{{ 'APP.OIDC.CLIENTID' | translate }} @@ -141,89 +196,46 @@ {{'APP.OIDC.CLOCKSKEW' | translate}} - - -
- -

{{'APP.OIDC.REDIRECTSECTIONTITLE' | translate}}

- - - {{ 'APP.OIDC.DEVMODE' | translate }} - - - - {{'APP.OIDC.DEVMODEDESC' | translate}} - - - - {{'APP.OIDC.REDIRECTDESCRIPTIONNATIVE' | translate}} - - -

- {{'APP.OIDC.REDIRECTDESCRIPTIONWEB' | translate}}

- - - - {{ 'APP.OIDC.REDIRECT' | translate }} - - - - - - - - {{redirect}} - cancel - - - -

- {{'APP.OIDC.REDIRECTNOTVALID' | translate}}

- -
- - {{ 'APP.OIDC.POSTLOGOUTREDIRECT' | translate }} - - - - - - - {{redirect}} - cancel - - - -

- {{'APP.OIDC.REDIRECTNOTVALID' | translate}}

-
+ - +
+ +
+ + +
+
{{'APP.PAGES.NEXTSTEPS.TITLE' | translate}}
+
+
+
{{ 'APP.PAGES.NEXTSTEPS.0.TITLE' | translate }}
+

{{'APP.PAGES.NEXTSTEPS.0.DESC' | translate}}

+ +
- - - +
+
{{ 'APP.PAGES.NEXTSTEPS.1.TITLE' | translate }}
+

{{'APP.PAGES.NEXTSTEPS.1.DESC' | translate}}

+ + +
+
+
{{ 'APP.PAGES.NEXTSTEPS.2.TITLE' | translate }}
+

{{'APP.PAGES.NEXTSTEPS.2.DESC' | translate}}

+ + +
+
+
+
diff --git a/console/src/app/pages/projects/apps/app-detail/app-detail.component.scss b/console/src/app/pages/projects/apps/app-detail/app-detail.component.scss index db7946ac7..894f809cc 100644 --- a/console/src/app/pages/projects/apps/app-detail/app-detail.component.scss +++ b/console/src/app/pages/projects/apps/app-detail/app-detail.component.scss @@ -8,11 +8,21 @@ display: block; } - h1 { - font-size: 1.2rem; - margin: 0 1rem; + .title-col { margin-left: 2rem; - font-weight: normal; + margin-right: 1rem; + min-width: 200px; + + h1 { + font-size: 1.2rem; + margin: 0 0 0 0; + font-weight: normal; + } + + span { + font-size: 12px; + color: var(--grey); + } } .desc { @@ -20,6 +30,7 @@ display: block; font-size: .9rem; color: var(--grey); + margin-top: 1.5rem; } .zitadel-warning { @@ -41,10 +52,10 @@ display: flex; flex-direction: row; flex-wrap: wrap; + align-items: center; .toggle { outline: none; - align-self: flex-start; margin-top: 1rem; margin-right: 1rem; border-radius: .5rem; @@ -91,6 +102,11 @@ align-items: center; } + .redirect-section { + flex: 1; + margin: 0 .5rem; + } + .formfield { flex: 1 1 30%; margin: 0 .5rem; @@ -99,27 +115,9 @@ flex-basis: 100%; } } - - .chiplist { - margin-bottom: 1rem; - } - - .chip-form { - width: 100%; - display: flex; - align-items: center; - - .formfield { - flex: 1; - } - - button { - margin-top: 1rem; - } - } - + .section-title { - margin-bottom: 1.5rem; + margin: 1.5rem 0 0 0; } .full-width { @@ -142,7 +140,7 @@ .desc { color: var(--grey); font-size: 14px; - margin-bottom: 1rem; + margin-bottom: 1.5rem; } .devmode { @@ -170,18 +168,67 @@ margin-top: 1rem; } -.chip { - border-radius: 4px; - height: 40px; -} - -.chip[color='green'] { - background-color: #56a392 !important; -} - .divider { flex-basis: 100%; margin: 1.5rem .5rem; height: 1px; background-color: rgba(#8795a1, .2); } + +.next-steps { + h5 { + text-transform: uppercase; + font-size: 14px; + color: var(--grey); + } + + .row { + width: 100%; + display: flex; + overflow-x: auto; + + .step { + min-width: 220px; + max-width: 280px; + padding: 1rem; + margin: 0 .5rem; + border: 1px solid var(--grey); + border-radius: .5rem; + display: flex; + flex-direction: column; + align-items: center; + box-sizing: border-box; + flex: 1; + + h6 { + font-size: 1rem; + text-align: center; + margin: 0 0 1rem 0; + } + + p { + font-size: 14px; + text-align: center; + color: var(--grey); + } + + .fill-space { + flex: 1; + } + + button { + display: block; + margin: auto; + } + + &:first-child { + margin-left: 0; + } + + &:last-child { + margin-right: 0; + } + } + + } +} \ No newline at end of file diff --git a/console/src/app/pages/projects/apps/app-detail/app-detail.component.ts b/console/src/app/pages/projects/apps/app-detail/app-detail.component.ts index 2e4cf4a1c..4cc5c5ffd 100644 --- a/console/src/app/pages/projects/apps/app-detail/app-detail.component.ts +++ b/console/src/app/pages/projects/apps/app-detail/app-detail.component.ts @@ -4,12 +4,14 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; import { AbstractControl, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; import { MatButtonToggleChange } from '@angular/material/button-toggle'; import { MatDialog } from '@angular/material/dialog'; -import { ActivatedRoute, Params } from '@angular/router'; +import { ActivatedRoute, Params, Router } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; import { Duration } from 'google-protobuf/google/protobuf/duration_pb'; import { Subscription } from 'rxjs'; import { take } from 'rxjs/operators'; +import { RadioItemAuthType } from 'src/app/modules/app-radio/app-auth-method-radio/app-auth-method-radio.component'; import { ChangeType } from 'src/app/modules/changes/changes.component'; +import { WarnDialogComponent } from 'src/app/modules/warn-dialog/warn-dialog.component'; import { Application, AppState, @@ -27,11 +29,7 @@ import { ManagementService } from 'src/app/services/mgmt.service'; import { ToastService } from 'src/app/services/toast.service'; import { AppSecretDialogComponent } from '../app-secret-dialog/app-secret-dialog.component'; - -enum RedirectType { - REDIRECT = 'redirect', - POSTREDIRECT = 'postredirect', -} +import { CODE_METHOD, getAuthMethodFromPartialConfig, getPartialConfigFromAuthMethod, IMPLICIT_METHOD, PKCE_METHOD, PK_JWT_METHOD, POST_METHOD, CUSTOM_METHOD } from '../authmethods'; @Component({ selector: 'app-app-detail', @@ -39,12 +37,20 @@ enum RedirectType { styleUrls: ['./app-detail.component.scss'], }) export class AppDetailComponent implements OnInit, OnDestroy { + public editState: boolean = false; + public currentAuthMethod: string = CUSTOM_METHOD.key; + public initialAuthMethod: string = CUSTOM_METHOD.key; public canWrite: boolean = false; public errorMessage: string = ''; public removable: boolean = true; public addOnBlur: boolean = true; public readonly separatorKeysCodes: number[] = [ENTER, COMMA, SPACE]; + public authMethods: RadioItemAuthType[] = [ + PKCE_METHOD, + CODE_METHOD, + POST_METHOD, + ]; private subscription?: Subscription; public projectId: string = ''; public app!: Application.AsObject; @@ -78,11 +84,10 @@ export class AppDetailComponent implements OnInit, OnDestroy { public AppState: any = AppState; public appNameForm!: FormGroup; public appForm!: FormGroup; + public redirectUrisList: string[] = []; public postLogoutRedirectUrisList: string[] = []; - public RedirectType: any = RedirectType; - public isZitadel: boolean = false; public docs!: ZitadelDocs.AsObject; @@ -90,9 +95,6 @@ export class AppDetailComponent implements OnInit, OnDestroy { public OIDCAuthMethodType: any = OIDCAuthMethodType; public OIDCTokenType: any = OIDCTokenType; - public redirectControl: FormControl = new FormControl({ value: '', disabled: true }); - public postRedirectControl: FormControl = new FormControl({ value: '', disabled: true }); - public ChangeType: any = ChangeType; constructor( public translate: TranslateService, @@ -103,6 +105,7 @@ export class AppDetailComponent implements OnInit, OnDestroy { private dialog: MatDialog, private mgmtService: ManagementService, private authService: GrpcAuthService, + private router: Router, ) { this.appNameForm = this.fb.group({ state: [{ value: '', disabled: true }, []], @@ -145,12 +148,23 @@ export class AppDetailComponent implements OnInit, OnDestroy { this.mgmtService.GetApplicationById(projectid, id).then(app => { this.app = app.toObject(); this.appNameForm.patchValue(this.app); - console.log(this.app); + + this.getAuthMethodOptions(); + if (this.app.oidcConfig) { + this.initialAuthMethod = this.authMethodFromPartialConfig(this.app.oidcConfig); + this.currentAuthMethod = this.initialAuthMethod; + if (this.initialAuthMethod === CUSTOM_METHOD.key) { + if (!this.authMethods.includes(CUSTOM_METHOD)) { + this.authMethods.push(CUSTOM_METHOD); + } + } else { + this.authMethods = this.authMethods.filter(element => element != CUSTOM_METHOD); + } + } + if (allowed) { this.appNameForm.enable(); this.appForm.enable(); - this.redirectControl.enable(); - this.postRedirectControl.enable(); } if (this.app.oidcConfig?.redirectUrisList) { @@ -161,12 +175,22 @@ export class AppDetailComponent implements OnInit, OnDestroy { } if (this.app.oidcConfig?.clockSkew) { const inSecs = this.app.oidcConfig?.clockSkew.seconds + this.app.oidcConfig?.clockSkew.nanos / 100000; - console.log(inSecs); this.appForm.controls['clockSkewSeconds'].setValue(inSecs); } if (this.app.oidcConfig) { this.appForm.patchValue(this.app.oidcConfig); } + + this.appForm.valueChanges.subscribe(oidcConfig => { + this.initialAuthMethod = this.authMethodFromPartialConfig(oidcConfig); + if (this.initialAuthMethod === CUSTOM_METHOD.key) { + if (!this.authMethods.includes(CUSTOM_METHOD)) { + this.authMethods.push(CUSTOM_METHOD); + } + } else { + this.authMethods = this.authMethods.filter(element => element != CUSTOM_METHOD); + } + }); }).catch(error => { console.error(error); this.toast.showError(error); @@ -176,6 +200,69 @@ export class AppDetailComponent implements OnInit, OnDestroy { this.docs = (await this.mgmtService.GetZitadelDocs()).toObject(); } + private getAuthMethodOptions(): void { + switch (this.app.oidcConfig?.applicationType) { + case OIDCApplicationType.OIDCAPPLICATIONTYPE_NATIVE: + this.authMethods = [ + PKCE_METHOD, + CUSTOM_METHOD, + ]; + break; + case OIDCApplicationType.OIDCAPPLICATIONTYPE_WEB: + this.authMethods = [ + PKCE_METHOD, + CODE_METHOD, + POST_METHOD, + ]; + break; + case OIDCApplicationType.OIDCAPPLICATIONTYPE_USER_AGENT: + this.authMethods = [ + PKCE_METHOD, + IMPLICIT_METHOD, + ]; + break; + } + } + + public authMethodFromPartialConfig(config: OIDCConfig.AsObject): string { + const key = getAuthMethodFromPartialConfig(config); + return key; + } + + public setPartialConfigFromAuthMethod(authMethod: string): void { + const partialConfig = getPartialConfigFromAuthMethod(authMethod); + + if (partialConfig && this.app.oidcConfig) { + this.app.oidcConfig.responseTypesList = partialConfig.responseTypesList ?? []; + this.app.oidcConfig.grantTypesList = partialConfig.grantTypesList ?? []; + this.app.oidcConfig.authMethodType = partialConfig.authMethodType ?? OIDCAuthMethodType.OIDCAUTHMETHODTYPE_NONE; + this.appForm.patchValue(this.app.oidcConfig); + } + } + + public deleteApp(): void { + const dialogRef = this.dialog.open(WarnDialogComponent, { + data: { + confirmKey: 'ACTIONS.DELETE', + cancelKey: 'ACTIONS.CANCEL', + titleKey: 'APP.PAGES.DIALOG.DELETE.TITLE', + descriptionKey: 'APP.PAGES.DIALOG.DELETE.DESCRIPTION', + }, + width: '400px', + }); + dialogRef.afterClosed().subscribe(resp => { + if (resp && this.projectId && this.app.id) { + this.mgmtService.RemoveApplication(this.projectId, this.app.id).then(() => { + this.toast.showInfo('APP.TOAST.DELETED', true); + + this.router.navigate(['/projects', this.projectId]); + }).catch(error => { + this.toast.showError(error); + }); + } + }); + } + public changeState(event: MatButtonToggleChange): void { if (event.value === AppState.APPSTATE_ACTIVE) { this.mgmtService.ReactivateApplication(this.projectId, this.app.id).then(() => { @@ -192,40 +279,6 @@ export class AppDetailComponent implements OnInit, OnDestroy { } } - public add(input: any, target: RedirectType): void { - if (target === RedirectType.POSTREDIRECT && this.postRedirectControl.valid) { - if (input.value !== '' && input.value !== ' ' && input.value !== '/') { - this.postLogoutRedirectUrisList.push(input.value); - } - if (input) { - input.value = ''; - } - } else if (target === RedirectType.REDIRECT && this.redirectControl.valid) { - if (input.value !== '' && input.value !== ' ' && input.value !== '/') { - this.redirectUrisList.push(input.value); - } - if (input) { - input.value = ''; - } - } - } - - public remove(redirect: any, target: RedirectType): void { - if (target === RedirectType.POSTREDIRECT) { - const index = this.postLogoutRedirectUrisList.indexOf(redirect); - - if (index >= 0) { - this.postLogoutRedirectUrisList.splice(index, 1); - } - } else if (target === RedirectType.REDIRECT) { - const index = this.redirectUrisList.indexOf(redirect); - - if (index >= 0) { - this.redirectUrisList.splice(index, 1); - } - } - } - public saveApp(): void { if (this.appNameForm.valid) { this.app.name = this.name?.value; @@ -234,6 +287,7 @@ export class AppDetailComponent implements OnInit, OnDestroy { .UpdateApplication(this.projectId, this.app.id, this.name?.value) .then(() => { this.toast.showInfo('APP.TOAST.OIDCUPDATED', true); + this.editState = false; }) .catch(error => { this.toast.showError(error); @@ -282,10 +336,12 @@ export class AppDetailComponent implements OnInit, OnDestroy { dur.setNanos((Math.floor(this.clockSkewSeconds?.value % 1) * 10000)); req.setClockSkew(dur); } - console.log(req.toObject()); this.mgmtService .UpdateOIDCAppConfig(req) .then(() => { + if (this.app.oidcConfig) { + this.currentAuthMethod = this.authMethodFromPartialConfig(this.app.oidcConfig); + } this.toast.showInfo('APP.TOAST.OIDCUPDATED', true); }) .catch(error => { diff --git a/console/src/app/pages/projects/apps/apps.module.ts b/console/src/app/pages/projects/apps/apps.module.ts index ff7fd7c0a..e1c1593c1 100644 --- a/console/src/app/pages/projects/apps/apps.module.ts +++ b/console/src/app/pages/projects/apps/apps.module.ts @@ -19,6 +19,7 @@ import { MatTooltipModule } from '@angular/material/tooltip'; import { TranslateModule } from '@ngx-translate/core'; import { CopyToClipboardModule } from 'src/app/directives/copy-to-clipboard/copy-to-clipboard.module'; import { HasRoleModule } from 'src/app/directives/has-role/has-role.module'; +import { AppRadioModule } from 'src/app/modules/app-radio/app-radio.module'; import { CardModule } from 'src/app/modules/card/card.module'; import { ChangesModule } from 'src/app/modules/changes/changes.module'; import { InfoSectionModule } from 'src/app/modules/info-section/info-section.module'; @@ -29,15 +30,20 @@ import { AppCreateComponent } from './app-create/app-create.component'; import { AppDetailComponent } from './app-detail/app-detail.component'; import { AppSecretDialogComponent } from './app-secret-dialog/app-secret-dialog.component'; import { AppsRoutingModule } from './apps-routing.module'; +import { A11yModule } from '@angular/cdk/a11y'; +import { RedirectUrisComponent } from './redirect-uris/redirect-uris.component'; @NgModule({ declarations: [ AppCreateComponent, AppDetailComponent, AppSecretDialogComponent, + RedirectUrisComponent, ], imports: [ CommonModule, + A11yModule, + AppRadioModule, AppsRoutingModule, FormsModule, TranslateModule, diff --git a/console/src/app/pages/projects/apps/authmethods.ts b/console/src/app/pages/projects/apps/authmethods.ts new file mode 100644 index 000000000..6d16c4ca0 --- /dev/null +++ b/console/src/app/pages/projects/apps/authmethods.ts @@ -0,0 +1,166 @@ +import { RadioItemAuthType } from 'src/app/modules/app-radio/app-auth-method-radio/app-auth-method-radio.component'; +import { OIDCAuthMethodType, OIDCConfig, OIDCGrantType, OIDCResponseType } from 'src/app/proto/generated/management_pb'; + +export const CODE_METHOD: RadioItemAuthType = { + key: 'CODE', + titleI18nKey: 'APP.OIDC.SELECTION.AUTHMETHOD.CODE.TITLE', + descI18nKey: 'APP.OIDC.SELECTION.AUTHMETHOD.CODE.DESCRIPTION', + disabled: false, + prefix: 'CODE', + background: 'rgb(89 115 128)', + responseType: OIDCResponseType.OIDCRESPONSETYPE_CODE, + grantType: OIDCGrantType.OIDCGRANTTYPE_AUTHORIZATION_CODE, + authMethod: OIDCAuthMethodType.OIDCAUTHMETHODTYPE_BASIC, + recommended: false, +}; +export const PKCE_METHOD: RadioItemAuthType = { + key: 'PKCE', + titleI18nKey: 'APP.OIDC.SELECTION.AUTHMETHOD.PKCE.TITLE', + descI18nKey: 'APP.OIDC.SELECTION.AUTHMETHOD.PKCE.DESCRIPTION', + disabled: false, + prefix: 'PKCE', + background: 'rgb(80 110 92)', + responseType: OIDCResponseType.OIDCRESPONSETYPE_CODE, + grantType: OIDCGrantType.OIDCGRANTTYPE_AUTHORIZATION_CODE, + authMethod: OIDCAuthMethodType.OIDCAUTHMETHODTYPE_NONE, + recommended: true, +}; +export const POST_METHOD: RadioItemAuthType = { + key: 'POST', + titleI18nKey: 'APP.OIDC.SELECTION.AUTHMETHOD.POST.TITLE', + descI18nKey: 'APP.OIDC.SELECTION.AUTHMETHOD.POST.DESCRIPTION', + disabled: false, + prefix: 'POST', + background: '#595d80', + responseType: OIDCResponseType.OIDCRESPONSETYPE_CODE, + grantType: OIDCGrantType.OIDCGRANTTYPE_AUTHORIZATION_CODE, + authMethod: OIDCAuthMethodType.OIDCAUTHMETHODTYPE_POST, + notRecommended: true, +}; +export const PK_JWT_METHOD: RadioItemAuthType = { + key: 'PK_JWT', + titleI18nKey: 'APP.OIDC.SELECTION.AUTHMETHOD.ALTERNATIVE.TITLE', + descI18nKey: 'APP.OIDC.SELECTION.AUTHMETHOD.ALTERNATIVE.DESCRIPTION', + disabled: false, + prefix: 'PK_JWT', + background: '#6a506e', + responseType: OIDCResponseType.OIDCRESPONSETYPE_CODE, + grantType: OIDCGrantType.OIDCGRANTTYPE_AUTHORIZATION_CODE, + authMethod: OIDCAuthMethodType.OIDCAUTHMETHODTYPE_POST, +}; +export const IMPLICIT_METHOD: RadioItemAuthType = { + key: 'IMPLICIT', + titleI18nKey: 'APP.OIDC.SELECTION.AUTHMETHOD.IMPLICIT.TITLE', + descI18nKey: 'APP.OIDC.SELECTION.AUTHMETHOD.IMPLICIT.DESCRIPTION', + disabled: false, + prefix: 'IMP', + background: 'rgb(144 75 75)', + responseType: OIDCResponseType.OIDCRESPONSETYPE_ID_TOKEN, + grantType: OIDCGrantType.OIDCGRANTTYPE_IMPLICIT, + authMethod: OIDCAuthMethodType.OIDCAUTHMETHODTYPE_NONE, + notRecommended: true, +}; +export const CUSTOM_METHOD: RadioItemAuthType = { + key: 'CUSTOM', + titleI18nKey: 'APP.OIDC.SELECTION.AUTHMETHOD.CUSTOM.TITLE', + descI18nKey: 'APP.OIDC.SELECTION.AUTHMETHOD.CUSTOM.DESCRIPTION', + disabled: false, + prefix: 'CUSTOM', + background: '#333', +}; + +export function getPartialConfigFromAuthMethod(authMethod: string): Partial | undefined { + let config: Partial; + switch (authMethod) { + case CODE_METHOD.key: + config = { + responseTypesList: [OIDCResponseType.OIDCRESPONSETYPE_CODE], + grantTypesList: [OIDCGrantType.OIDCGRANTTYPE_AUTHORIZATION_CODE], + authMethodType: OIDCAuthMethodType.OIDCAUTHMETHODTYPE_BASIC, + }; + return config; + case PKCE_METHOD.key: + config = { + responseTypesList: [OIDCResponseType.OIDCRESPONSETYPE_CODE], + grantTypesList: [OIDCGrantType.OIDCGRANTTYPE_AUTHORIZATION_CODE], + authMethodType: OIDCAuthMethodType.OIDCAUTHMETHODTYPE_NONE, + }; + return config; + case POST_METHOD.key: + config = { + responseTypesList: [OIDCResponseType.OIDCRESPONSETYPE_CODE], + grantTypesList: [OIDCGrantType.OIDCGRANTTYPE_AUTHORIZATION_CODE], + authMethodType: OIDCAuthMethodType.OIDCAUTHMETHODTYPE_POST, + }; + return config; + // case PK_JWT_METHOD.key: + // config = { + // responseTypesList: [OIDCResponseType.OIDCRESPONSETYPE_CODE], + // grantTypesList: [OIDCGrantType.OIDCGRANTTYPE_AUTHORIZATION_CODE], + // authMethodType: OIDCAuthMethodType.OIDCAUTHMETHODTYPE_NONE, + // }; + // return config; + case IMPLICIT_METHOD.key: + config = { + responseTypesList: [OIDCResponseType.OIDCRESPONSETYPE_ID_TOKEN_TOKEN], + grantTypesList: [OIDCGrantType.OIDCGRANTTYPE_IMPLICIT], + authMethodType: OIDCAuthMethodType.OIDCAUTHMETHODTYPE_NONE, + }; + return config; + default: + return undefined; + } +} + +export function getAuthMethodFromPartialConfig(config: Partial | OIDCConfig.AsObject): string { + const toCheck = [config.responseTypesList, config.grantTypesList, config.authMethodType]; + const code = JSON.stringify( + [ + [OIDCResponseType.OIDCRESPONSETYPE_CODE], + [OIDCGrantType.OIDCGRANTTYPE_AUTHORIZATION_CODE], + OIDCAuthMethodType.OIDCAUTHMETHODTYPE_BASIC, + ] + ); + + const pkce = JSON.stringify( + [ + [OIDCResponseType.OIDCRESPONSETYPE_CODE], + [OIDCGrantType.OIDCGRANTTYPE_AUTHORIZATION_CODE], + OIDCAuthMethodType.OIDCAUTHMETHODTYPE_NONE, + ] + ); + + const post = JSON.stringify( + [ + [OIDCResponseType.OIDCRESPONSETYPE_CODE], + [OIDCGrantType.OIDCGRANTTYPE_AUTHORIZATION_CODE], + OIDCAuthMethodType.OIDCAUTHMETHODTYPE_POST, + ] + ); + + // const pk_jwt = JSON.stringify( + // [ + // [OIDCResponseType.OIDCRESPONSETYPE_CODE], + // [OIDCGrantType.OIDCGRANTTYPE_AUTHORIZATION_CODE], + // OIDCAuthMethodType.OIDCAUTHMETHODTYPE_BASIC, + // ] + // ); + + const implicit = JSON.stringify( + [ + [OIDCResponseType.OIDCRESPONSETYPE_ID_TOKEN_TOKEN], + [OIDCGrantType.OIDCGRANTTYPE_IMPLICIT], + OIDCAuthMethodType.OIDCAUTHMETHODTYPE_NONE, + ] + ); + + switch (JSON.stringify(toCheck)) { + case code: return CODE_METHOD.key; + case pkce: return PKCE_METHOD.key; + case post: return POST_METHOD.key; + // case pk_jwt: return PK_JWT_METHOD.key; + case implicit: return IMPLICIT_METHOD.key; + default: + return CUSTOM_METHOD.key; + } +} \ No newline at end of file diff --git a/console/src/app/pages/projects/apps/authtypes.ts b/console/src/app/pages/projects/apps/authtypes.ts new file mode 100644 index 000000000..9e352459e --- /dev/null +++ b/console/src/app/pages/projects/apps/authtypes.ts @@ -0,0 +1,25 @@ +import { OIDCApplicationType } from 'src/app/proto/generated/management_pb'; + +export const WEB_TYPE = { + titleI18nKey: 'APP.OIDC.SELECTION.APPTYPE.WEB.TITLE', + descI18nKey: 'APP.OIDC.SELECTION.APPTYPE.WEB.DESCRIPTION', + type: OIDCApplicationType.OIDCAPPLICATIONTYPE_WEB, + prefix: 'WEB', + background: 'rgb(80, 110, 110)', +}; + +export const USER_AGENT_TYPE = { + titleI18nKey: 'APP.OIDC.SELECTION.APPTYPE.USERAGENT.TITLE', + descI18nKey: 'APP.OIDC.SELECTION.APPTYPE.USERAGENT.DESCRIPTION', + type: OIDCApplicationType.OIDCAPPLICATIONTYPE_USER_AGENT, + prefix: 'UA', + background: '#6a506e', +}; + +export const NATIVE_TYPE = { + titleI18nKey: 'APP.OIDC.SELECTION.APPTYPE.NATIVE.TITLE', + descI18nKey: 'APP.OIDC.SELECTION.APPTYPE.NATIVE.DESCRIPTION', + type: OIDCApplicationType.OIDCAPPLICATIONTYPE_NATIVE, + prefix: 'N', + background: '#595d80', +}; diff --git a/console/src/app/pages/projects/apps/redirect-uris/redirect-uris.component.html b/console/src/app/pages/projects/apps/redirect-uris/redirect-uris.component.html new file mode 100644 index 000000000..036853c5f --- /dev/null +++ b/console/src/app/pages/projects/apps/redirect-uris/redirect-uris.component.html @@ -0,0 +1,28 @@ +
+ + {{ title }} + + + + + + +
+
+ {{uri}} + + + + + +
+
+ +

+ {{'APP.OIDC.REDIRECTNOTVALID' | translate}}

\ No newline at end of file diff --git a/console/src/app/pages/projects/apps/redirect-uris/redirect-uris.component.scss b/console/src/app/pages/projects/apps/redirect-uris/redirect-uris.component.scss new file mode 100644 index 000000000..9645db0a6 --- /dev/null +++ b/console/src/app/pages/projects/apps/redirect-uris/redirect-uris.component.scss @@ -0,0 +1,61 @@ +.form { + display: flex; + align-items: flex-end; + min-width: 320px; + + .formfield { + flex: 1; + } + + button { + margin-bottom: 14px; + margin-right: -0.5rem; + } +} +.uri-list { + margin: 0 .5rem; + width: 100%; + + .uri-line { + display: flex; + align-items: center; + + .uri { + font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; + font-size: 14px; + } + + .fill-space { + flex: 1; + } + + i.green { + font-size: 1rem; + line-height: 35px; + height: 30px; + } + + i.red { + font-size: 1.2rem; + } + + .icon-button { + height: 30px; + line-height: 30px; + + mat-icon { + font-size: 1rem !important; + } + + &:not(:hover) { + color: var(--grey); + } + } + } +} + +.error { + font-size: 13px; + color: #f44336; + margin: 0 .5rem 1.5rem .5rem; +} \ No newline at end of file diff --git a/console/src/app/pages/projects/apps/redirect-uris/redirect-uris.component.spec.ts b/console/src/app/pages/projects/apps/redirect-uris/redirect-uris.component.spec.ts new file mode 100644 index 000000000..a09b84deb --- /dev/null +++ b/console/src/app/pages/projects/apps/redirect-uris/redirect-uris.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { RedirectUrisComponent } from './redirect-uris.component'; + +describe('RedirectUrisComponent', () => { + let component: RedirectUrisComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ RedirectUrisComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(RedirectUrisComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/console/src/app/pages/projects/apps/redirect-uris/redirect-uris.component.ts b/console/src/app/pages/projects/apps/redirect-uris/redirect-uris.component.ts new file mode 100644 index 000000000..3cf7083e5 --- /dev/null +++ b/console/src/app/pages/projects/apps/redirect-uris/redirect-uris.component.ts @@ -0,0 +1,43 @@ +import { Component, EventEmitter, Input, OnInit } from '@angular/core'; +import { FormControl } from '@angular/forms'; + +@Component({ + selector: 'cnsl-redirect-uris', + templateUrl: './redirect-uris.component.html', + styleUrls: ['./redirect-uris.component.scss'] +}) +export class RedirectUrisComponent implements OnInit { + @Input() title: string = ''; + @Input() devMode: boolean = false; + @Input() canWrite: boolean = false; + @Input() public urisList: string[] = []; + @Input() public redirectControl: FormControl = new FormControl({ value: '', disabled: true }); + @Input() public changedUris: EventEmitter = new EventEmitter(); + constructor() { } + + ngOnInit(): void { + if (this.canWrite) { + this.redirectControl.enable(); + } + } + + public add(input: any): void { + if (this.redirectControl.valid) { + if (input.value !== '' && input.value !== ' ' && input.value !== '/') { + this.urisList.push(input.value); + } + if (input) { + input.value = ''; + } + } + } + + public remove(redirect: any): void { + console.log(redirect); + const index = this.urisList.indexOf(redirect); + + if (index >= 0) { + this.urisList.splice(index, 1); + } + } +} diff --git a/console/src/app/pages/projects/owned-projects/owned-project-detail/application-grid/application-grid.component.html b/console/src/app/pages/projects/owned-projects/owned-project-detail/application-grid/application-grid.component.html index b34e25bda..2d0ab1c56 100644 --- a/console/src/app/pages/projects/owned-projects/owned-project-detail/application-grid/application-grid.component.html +++ b/console/src/app/pages/projects/owned-projects/owned-project-detail/application-grid/application-grid.component.html @@ -11,18 +11,27 @@
-
+ *ngFor="let app of appsSubject | async" + matTooltip="{{'APP.OIDC.APPTYPE'+app.oidcConfig.applicationType | translate}}"> + {{ app.name.charAt(0)}} -
+ + + + {{app.name}} + {{'APP.OIDC.APPTYPE'+app.oidcConfig.applicationType | translate}} +
-
+ add -
+ {{ 'ACTIONS.NEW' | translate }}
diff --git a/console/src/app/pages/projects/owned-projects/owned-project-detail/application-grid/application-grid.component.scss b/console/src/app/pages/projects/owned-projects/owned-project-detail/application-grid/application-grid.component.scss index 4781ae077..14c580397 100644 --- a/console/src/app/pages/projects/owned-projects/owned-project-detail/application-grid/application-grid.component.scss +++ b/console/src/app/pages/projects/owned-projects/owned-project-detail/application-grid/application-grid.component.scss @@ -1,82 +1,62 @@ -@import '~@angular/material/theming'; -@mixin application-grid-theme($theme) { - /* stylelint-disable */ - $primary: map-get($theme, primary); - $primary-dark: mat-color($primary, A900); - $accent: map-get($theme, accent); - $accent-color: mat-color($primary, 500); - /* stylelint-enable */ - .app-grid-header { +.app-grid-header { display: flex; align-items: center; .fill-space { - flex: 1; + flex: 1; } - } +} - .app-container { +.app-container { display: flex; flex-wrap: wrap; margin: 0 -1rem; padding-bottom: 2rem; .sp-container { - display: flex; - justify-content: center; - align-items: center; - width: calc(82px + 2rem); - height: calc(82px + 2rem); - } - - .app-wrap { - outline: none; - display: flex; - flex-direction: column; - align-items: center; - max-width: 150px; - - .morph-card { - cursor: pointer; - animation: all .2s; display: flex; justify-content: center; align-items: center; - font-size: 2rem; - height: 80px; - width: 80px; - margin: 1rem; - text-transform: uppercase; - border-radius: .5rem; - border: 2px solid $accent-color; - font-weight: 800; - background-color: $primary-dark; - transition: background-color box-shadow .3s ease-in; - background-image: - linear-gradient(transparent 11px, rgba($accent-color, .5) 12px, transparent 12px), - linear-gradient(90deg, transparent 11px, rgba($accent-color, .5) 12px, transparent 12px); - background-size: 100% 12px, 12px 100%; + width: calc(82px + 2rem); + height: calc(82px + 2rem); + } - &:hover { - background-color: rgba($accent-color, .1); + .app-wrap { + outline: none; + display: flex; + flex-direction: column; + align-items: center; + max-width: 150px; + + .grid-card { + cursor: pointer; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + font-size: 2rem; + height: 80px; + width: 80px; + margin: 1rem; + text-transform: uppercase; + border-radius: .5rem; + font-weight: 800; + box-sizing: border-box; + + &.add { + border: 2px solid var(--grey); + } } - &.add { - background: $accent-color; - color: white; + .name { + font-size: 14px; + } - &:hover { - background-color: rgba($accent-color, .8); - } + .type { + font-size: 12px; + color: #8a868a; } - } - - .name { - font-size: .8rem; - color: #8a868a; - } } - } } diff --git a/console/src/app/pages/projects/owned-projects/owned-project-detail/application-grid/application-grid.component.ts b/console/src/app/pages/projects/owned-projects/owned-project-detail/application-grid/application-grid.component.ts index e0e26b06c..a73e8687c 100644 --- a/console/src/app/pages/projects/owned-projects/owned-project-detail/application-grid/application-grid.component.ts +++ b/console/src/app/pages/projects/owned-projects/owned-project-detail/application-grid/application-grid.component.ts @@ -1,8 +1,9 @@ import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; import { BehaviorSubject, from, Observable, of } from 'rxjs'; import { catchError, finalize, map } from 'rxjs/operators'; -import { Application } from 'src/app/proto/generated/management_pb'; +import { Application, OIDCApplicationType, OIDCResponseType } from 'src/app/proto/generated/management_pb'; import { ManagementService } from 'src/app/services/mgmt.service'; +import { NATIVE_TYPE, USER_AGENT_TYPE, WEB_TYPE } from '../../../apps/authtypes'; @Component({ selector: 'app-application-grid', @@ -16,6 +17,11 @@ export class ApplicationGridComponent implements OnInit { public appsSubject: BehaviorSubject = new BehaviorSubject([]); private loadingSubject: BehaviorSubject = new BehaviorSubject(true); public loading$: Observable = this.loadingSubject.asObservable(); + public OIDCApplicationType: any = OIDCApplicationType; + + public NATIVE_TYPE: any = NATIVE_TYPE; + public WEB_TYPE: any = WEB_TYPE; + public USER_AGENT_TYPE: any = USER_AGENT_TYPE; constructor(private mgmtService: ManagementService) { } diff --git a/console/src/app/pages/projects/owned-projects/owned-project-detail/applications/applications.component.html b/console/src/app/pages/projects/owned-projects/owned-project-detail/applications/applications.component.html index 9012cba3a..21445b24e 100644 --- a/console/src/app/pages/projects/owned-projects/owned-project-detail/applications/applications.component.html +++ b/console/src/app/pages/projects/owned-projects/owned-project-detail/applications/applications.component.html @@ -24,10 +24,17 @@ -
- + + + + + + + diff --git a/console/src/app/pages/projects/owned-projects/owned-project-detail/applications/applications.component.ts b/console/src/app/pages/projects/owned-projects/owned-project-detail/applications/applications.component.ts index bbfb36ef0..c4b70f143 100644 --- a/console/src/app/pages/projects/owned-projects/owned-project-detail/applications/applications.component.ts +++ b/console/src/app/pages/projects/owned-projects/owned-project-detail/applications/applications.component.ts @@ -26,7 +26,7 @@ export class ApplicationsComponent implements AfterViewInit, OnInit { public dataSource!: ProjectApplicationsDataSource; public selection: SelectionModel = new SelectionModel(true, []); - public displayedColumns: string[] = ['select', 'name']; + public displayedColumns: string[] = ['select', 'name', 'type']; constructor(private mgmtService: ManagementService, private toast: ToastService) { } diff --git a/console/src/app/pages/projects/owned-projects/owned-project-detail/owned-project-detail.component.html b/console/src/app/pages/projects/owned-projects/owned-project-detail/owned-project-detail.component.html index 5a336524a..d83a9208e 100644 --- a/console/src/app/pages/projects/owned-projects/owned-project-detail/owned-project-detail.component.html +++ b/console/src/app/pages/projects/owned-projects/owned-project-detail/owned-project-detail.component.html @@ -8,7 +8,7 @@ @@ -24,11 +24,13 @@ + (click)="changeState(ProjectState.PROJECTSTATE_INACTIVE)">{{'PROJECT.TABLE.DEACTIVATE' | + translate}} + (click)="changeState(ProjectState.PROJECTSTATE_ACTIVE)">{{'PROJECT.TABLE.ACTIVATE' | + translate}}
@@ -78,7 +80,7 @@ -

{{'PROJECT.ROLE.OPTIONS' | translate}}

{{'PROJECT.STATE.TITLE' | translate}}: {{'PROJECT.STATE.'+project.state | translate}} + [ngClass]="{'active': project.state === ProjectState.PROJECTSTATE_ACTIVE, 'inactive': project.state === ProjectState.PROJECTSTATE_INACTIVE}">{{'PROJECT.STATE.'+project.state + | translate}}
diff --git a/console/src/app/pages/projects/owned-projects/owned-project-detail/owned-project-detail.module.ts b/console/src/app/pages/projects/owned-projects/owned-project-detail/owned-project-detail.module.ts index 269742928..04d52105a 100644 --- a/console/src/app/pages/projects/owned-projects/owned-project-detail/owned-project-detail.module.ts +++ b/console/src/app/pages/projects/owned-projects/owned-project-detail/owned-project-detail.module.ts @@ -14,6 +14,7 @@ import { MatTooltipModule } from '@angular/material/tooltip'; import { TranslateModule } from '@ngx-translate/core'; import { HasRoleModule } from 'src/app/directives/has-role/has-role.module'; import { MemberCreateDialogModule } from 'src/app/modules/add-member-dialog/member-create-dialog.module'; +import { AppCardModule } from 'src/app/modules/app-card/app-card.module'; import { CardModule } from 'src/app/modules/card/card.module'; import { ChangesModule } from 'src/app/modules/changes/changes.module'; import { ContributorsModule } from 'src/app/modules/contributors/contributors.module'; @@ -43,6 +44,7 @@ import { ProjectGrantsComponent } from './project-grants/project-grants.componen imports: [ CommonModule, FormsModule, + AppCardModule, OwnedProjectDetailRoutingModule, TranslateModule, ReactiveFormsModule, diff --git a/console/src/app/pages/projects/owned-projects/project-grant-detail/project-grant-detail.component.html b/console/src/app/pages/projects/owned-projects/project-grant-detail/project-grant-detail.component.html index 6e7215136..031c08886 100644 --- a/console/src/app/pages/projects/owned-projects/project-grant-detail/project-grant-detail.component.html +++ b/console/src/app/pages/projects/owned-projects/project-grant-detail/project-grant-detail.component.html @@ -39,7 +39,7 @@

{{ 'PROJECT.GRANT.DETAIL.MEMBERTITLE' | translate }}

{{ 'PROJECT.GRANT.DETAIL.MEMBERDESC' | translate }}

- + \ No newline at end of file diff --git a/console/src/app/pages/signedout/signedout.component.scss b/console/src/app/pages/signedout/signedout.component.scss index 1577de9c7..d5320c36a 100644 --- a/console/src/app/pages/signedout/signedout.component.scss +++ b/console/src/app/pages/signedout/signedout.component.scss @@ -17,19 +17,24 @@ p { color: var(--grey); text-align: center; - font-size: 1rem; + font-size: 14px; margin: 0; margin-bottom: 3rem; } img { height: 100px; + max-width: 170px; margin-bottom: 2rem; } button { display: block; padding: .5rem 4rem; + + i { + margin-left: .5rem; + } } } } diff --git a/console/src/app/pages/users/user-detail/auth-user-detail/auth-user-detail.component.html b/console/src/app/pages/users/user-detail/auth-user-detail/auth-user-detail.component.html index e28affdae..9131ff01a 100644 --- a/console/src/app/pages/users/user-detail/auth-user-detail/auth-user-detail.component.html +++ b/console/src/app/pages/users/user-detail/auth-user-detail/auth-user-detail.component.html @@ -77,7 +77,7 @@ - + diff --git a/console/src/app/pages/users/user-detail/memberships/memberships.component.ts b/console/src/app/pages/users/user-detail/memberships/memberships.component.ts index 68b3d7ece..c4b261099 100644 --- a/console/src/app/pages/users/user-detail/memberships/memberships.component.ts +++ b/console/src/app/pages/users/user-detail/memberships/memberships.component.ts @@ -3,8 +3,10 @@ import { Component, Input, OnInit } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { Router } from '@angular/router'; import { CreationType, MemberCreateDialogComponent } from 'src/app/modules/add-member-dialog/member-create-dialog.component'; +import { AuthServiceClient } from 'src/app/proto/generated/auth_grpc_web_pb'; import { MemberType, UserMembershipSearchResponse, UserView } from 'src/app/proto/generated/management_pb'; import { AdminService } from 'src/app/services/admin.service'; +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'; @@ -33,12 +35,14 @@ export class MembershipsComponent implements OnInit { public loading: boolean = false; public memberships!: UserMembershipSearchResponse.AsObject; + @Input() public auth: boolean = false; @Input() public user!: UserView.AsObject; @Input() public disabled: boolean = false; public MemberType: any = MemberType; constructor( + private authService: GrpcAuthService, private mgmtService: ManagementService, private adminService: AdminService, private dialog: MatDialog, @@ -51,10 +55,17 @@ export class MembershipsComponent implements OnInit { } public async loadManager(userId: string): Promise { - this.mgmtService.SearchUserMemberships(userId, 100, 0, []).then(response => { - this.memberships = response.toObject(); - this.loading = false; - }); + if (this.auth) { + this.authService.SearchUserMemberships(100, 0, []).then(response => { + this.memberships = response.toObject(); + this.loading = false; + }); + } else { + this.mgmtService.SearchUserMemberships(userId, 100, 0, []).then(response => { + this.memberships = response.toObject(); + this.loading = false; + }); + } } public navigateToObject(): void { diff --git a/console/src/app/pages/users/user-detail/user-detail/user-detail.component.scss b/console/src/app/pages/users/user-detail/user-detail/user-detail.component.scss index 0f113e67c..154ae46fb 100644 --- a/console/src/app/pages/users/user-detail/user-detail/user-detail.component.scss +++ b/console/src/app/pages/users/user-detail/user-detail/user-detail.component.scss @@ -1,7 +1,6 @@ .head { display: flex; align-items: center; - border-bottom: 1px solid #ffffff20; flex-wrap: wrap; padding-bottom: .5rem; diff --git a/console/src/app/services/grpc-auth.service.ts b/console/src/app/services/grpc-auth.service.ts index 0022c2412..915cdcdfb 100644 --- a/console/src/app/services/grpc-auth.service.ts +++ b/console/src/app/services/grpc-auth.service.ts @@ -26,6 +26,9 @@ import { UpdateUserProfileRequest, UserAddress, UserEmail, + UserMembershipSearchQuery, + UserMembershipSearchRequest, + UserMembershipSearchResponse, UserPhone, UserProfile, UserProfileView, @@ -241,6 +244,16 @@ export class GrpcAuthService { ); } + public SearchUserMemberships(limit: number, offset: number, queryList?: UserMembershipSearchQuery[]): Promise { + const req = new UserMembershipSearchRequest(); + req.setLimit(limit); + req.setOffset(offset); + if (queryList) { + req.setQueriesList(queryList); + } + return this.grpcService.auth.searchMyUserMemberships(req); + } + public GetMyUserEmail(): Promise { return this.grpcService.auth.getMyUserEmail( new Empty(), diff --git a/console/src/app/services/interceptors/auth.interceptor.ts b/console/src/app/services/interceptors/auth.interceptor.ts index 37b1371dc..08e13e0ab 100644 --- a/console/src/app/services/interceptors/auth.interceptor.ts +++ b/console/src/app/services/interceptors/auth.interceptor.ts @@ -55,6 +55,7 @@ export class AuthInterceptor implements UnaryIn titleKey: 'ERRORS.TOKENINVALID.TITLE', descriptionKey: 'ERRORS.TOKENINVALID.DESCRIPTION', }, + disableClose: true, width: '400px', }); diff --git a/console/src/app/services/mgmt.service.ts b/console/src/app/services/mgmt.service.ts index f76b8f5cc..0af115296 100644 --- a/console/src/app/services/mgmt.service.ts +++ b/console/src/app/services/mgmt.service.ts @@ -1362,4 +1362,11 @@ export class ManagementService { public UpdateOIDCAppConfig(req: OIDCConfigUpdate): Promise { return this.grpcService.mgmt.updateApplicationOIDCConfig(req); } + + public RemoveApplication(projectId: string, appId: string): Promise { + const req = new ApplicationID(); + req.setId(appId); + req.setProjectId(projectId); + return this.grpcService.mgmt.removeApplication(req); + } } diff --git a/console/src/assets/i18n/de.json b/console/src/assets/i18n/de.json index 7f12d7b93..c6b055be7 100644 --- a/console/src/assets/i18n/de.json +++ b/console/src/assets/i18n/de.json @@ -1,5 +1,29 @@ { "APP_NAME": "ZITADEL", + "ONBOARDING": { + "HEADER":"Erste Schritte", + "TITLE":"Lernen Sie unsere ZITADEL Console kennen.", + "LOGINDESC":"Melden Sie sich an um Zugriff auf Funktionen von Zitadel zu erhalten", + "LOGIN":"Anmelden", + "DESCRIPTION":"Führen Sie die folgenden Schritte aus und passen Sie ZITADEL optimal an Ihre Bedürfnisse an.", + "STEPS_TITLE":"Führen Sie die folgenden Schritte in gewünschter Reihenfolge aus:", + "STEPS": { + "1": { + "TITLE":"Projekt erstellen", + "DESC":"Erstellen Sie Ihr erstes Projekt und legen Sie Zugangsberechtigungen eventueller Mitarbeiter fest." + }, + "2": { + "TITLE":"Applikation erstellen", + "DESC":"Erstellen Sie eine Applikation innerhalb Ihres Projektes und legen Sie dessen Eigenschaften fest." + }, + "3": { + "TITLE":"Sicherheit verbessern", + "DESC":"Erweitern Sie die Zugangsrichtlinien und erhöhen Sie dadurch die Sicherheit ihrer Benutzer." + } + }, + "START":"Start", + "DOCS":"Docs" + }, "HOME": { "TITLE": "ZITADEL", "SECURITYANDPRIVACY": "Datenschutz und Personalisierung", @@ -32,9 +56,15 @@ "WELCOME":"Willkommen", "WELCOMESENTENCE":"Hier findest Du die empfohlenen Aktionen basierend auf Deinen zuletzt erworbenen Berechtigungen. Beachte bitte, dass Du möglicherweise Deine Organisation in der Kopfzeile wechseln musst.", "DISCLAIMER":"Du kannst nur die Einstellungen Deiner aktuellen Organisation, die in der Kopfzeile angegeben ist, sehen. ZITADEL behandelt Deine Daten vertraulich und sicher.", - "DISCLAIMERLINK":"Mehr Informationen zur Sicherheit" + "DISCLAIMERLINK":"Mehr Informationen zur Sicherheit", + "QUICKSTARTS": { + "LABEL":"Erste Schritte", + "TITLE":"Quickstarts", + "DESCRIPTION":"Mit ZITADEL schnell durchstarten." + } }, "MENU": { + "DASHBOARD":"Übersicht", "PERSONAL_INFO": "Persönliche Informationen", "DOCUMENTATION":"Dokumentation", "IAMPOLICIES":"IAM", @@ -54,6 +84,7 @@ "SHOWORGS":"Alle Organisationen anzeigen", "GRANTSECTION":"Berechtigungssektion", "GRANTS":"Berechtigungen", + "TOC":"Datenschutz und AGB", "TOOLTIP": { "PERSONAL":"Verwalte deinen persönlichen Account, deine IDPs, Login Methoden, Faktoren und Berechtigungen", "IAMPOLICIES":"Verwalte ZITADELs globale Zugangsrichtlinien und verwalte ZITADEL Manager", @@ -930,12 +961,34 @@ "1": "Aktiv", "2": "Inaktiv" } + }, + "DIALOG": { + "DELETE": { + "TITLE": "App löschen", + "DESCRIPTION":"Wollen Sie diese App wirklich löschen?" + } + }, + "NEXTSTEPS": { + "TITLE":"Nächste Schritte", + "0": { + "TITLE":"Rollen festlegen", + "DESC":"Erfassen Sie Rollen für ihr Projekt" + }, + "1": { + "TITLE":"Benutzer hinzufügen", + "DESC":"Fügen Sie Nutzer ihrer Organisation hinzu" + }, + "2": { + "TITLE":"Hilfe & Support", + "DESC":"Lesen Sie unsere Dokumentation zum Erstellen von Applikation oder kontaktieren Sie unseren Support" + } } }, "NAME": "Name", "TYPE":"Anwendungstyp", "GRANT":"Berechtigungstypen", "OIDC": { + "CURRENT":"Aktuelle Konfiguration", "TOKENSECTIONTITLE":"AuthToken Optionen", "REDIRECTSECTIONTITLE":"Weiterleitungseinstellungen", "PROSWITCH":"Konfigurator überspringen", @@ -991,13 +1044,58 @@ "IDTOKENROLEASSERTION_DESCRIPTION":"Bei Auswahl werden dem Id Token die Rollen des Authentifizierten Benutzers hinzugefügt.", "IDTOKENUSERINFOASSERTION":"User Info im ID Token", "IDTOKENUSERINFOASSERTION_DESCRIPTION":"Ermöglich OIDC clients claims von profile, email, phone und address direkt vom ID Token zu beziehen.", - "CLOCKSKEW":"ermöglicht Clients, den Taktversatz von OP und Client zu verarbeiten. Die Dauer (0-5s) wird der exp addiert und von iats, auth_time und nbf abgezogen." + "CLOCKSKEW":"ermöglicht Clients, den Taktversatz von OP und Client zu verarbeiten. Die Dauer (0-5s) wird der exp addiert und von iats, auth_time und nbf abgezogen.", + "RECOMMENDED":"Empfohlen", + "NOTRECOMMENDED":"nicht empfohlen", + "SELECTION":{ + "APPTYPE": { + "WEB": { + "TITLE":"Web", + "DESCRIPTION":"Standard Web applications wie .net, PHP, Node.js, Java, etc." + }, + "NATIVE": { + "TITLE":"NATIVE", + "DESCRIPTION":"Mobile Apps, Desktop, Smart Devices, etc." + }, + "USERAGENT": { + "TITLE":"User Agent", + "DESCRIPTION":"Single Page Applications (SPA) und grundsätzlich alle im Browser aufgeführten JS Frameworks" + } + }, + "AUTHMETHOD": { + "CODE": { + "TITLE":"Code", + "DESCRIPTION":"Tausche den Authorization Code gegen Tokens ein" + }, + "PKCE": { + "TITLE":"PKCE", + "DESCRIPTION":"Nutze einen Zufalls Hash Wert anstelle des Client Secret für mehr Sicherheit" + }, + "POST": { + "TITLE":"POST", + "DESCRIPTION":"Sende client_id und client_secret im (HTML) Formular" + }, + "PK_JWT": { + "TITLE":"Private Key JWT", + "DESCRIPTION":"Nutze einen Private Key um deine Application zu authentifizieren" + }, + "IMPLICIT": { + "TITLE":"Implicit", + "DESCRIPTION":"Erhalte die Token direkt vom authorize Endpoint" + }, + "CUSTOM": { + "TITLE":"Custom", + "DESCRIPTION":"Deine Konfiguration entspricht keiner anderen Option." + } + } + } }, "TOAST": { "REACTIVATED":"Anwendung reaktiviert.", "DEACTIVATED":"Anwendung deaktiviert.", "OIDCUPDATED":"OIDC-Konfiguration geändert.", - "OIDCCLIENTSECRETREGENERATED":"OIDC-Client Secret generiert." + "OIDCCLIENTSECRETREGENERATED":"OIDC-Client Secret generiert.", + "DELETED":"App gelöscht." } }, "GENDERS": { diff --git a/console/src/assets/i18n/en.json b/console/src/assets/i18n/en.json index ee90a3b6c..36f606c5f 100644 --- a/console/src/assets/i18n/en.json +++ b/console/src/assets/i18n/en.json @@ -1,5 +1,29 @@ { "APP_NAME": "ZITADEL", + "ONBOARDING": { + "HEADER":"First Steps", + "TITLE":"Learn how to use ZITADEL", + "LOGINDESC":"You need to log in to control your ZITADEL settings.", + "LOGIN":"Login", + "DESCRIPTION":"We at ZITADEL care a lot about security and performance. Carry out the following steps and adapt ZITADEL optimally to your needs.", + "STEPS_TITLE":"Complete the following steps in the order you want:", + "STEPS": { + "1": { + "TITLE":"Create a project", + "DESC":"Create your first project and define access rights for any employees." + }, + "2": { + "TITLE":"Create Application", + "DESC":"Create an application within your project and define its properties." + }, + "3": { + "TITLE":"Improve security", + "DESC":"Extend the access policies and thereby increase the security of your users." + } + }, + "START":"Start", + "DOCS":"Docs" + }, "HOME": { "TITLE": "ZITADEL", "SECURITYANDPRIVACY": "Data Protection and Personalisation", @@ -32,9 +56,15 @@ "WELCOME":"Welcome", "WELCOMESENTENCE":"Here you can find recommended actions based on your last acquired permissions. Note that you may have to select your organisation in the header above.", "DISCLAIMER":"You can only see settings of your current organisation specified in the header. ZITADEL treats your data confidentially and securely.", - "DISCLAIMERLINK":"Further information" + "DISCLAIMERLINK":"Further information", + "QUICKSTARTS": { + "LABEL":"First Steps", + "TITLE":"Quickstarts", + "DESCRIPTION":"Get started with ZITADEL quickly." + } }, "MENU": { + "DASHBOARD":"Overview", "PERSONAL_INFO": "Personal Information", "DOCUMENTATION":"Documentation", "IAMPOLICIES":"IAM", @@ -54,6 +84,7 @@ "SHOWORGS":"Show All Organisations", "GRANTSECTION":"Authorization Section", "GRANTS":"Authorizations", + "TOC":"Privacy Policy and TOC", "TOOLTIP": { "PERSONAL":"Show your Personal Account, your IDPs, Login methods, Factors and Authorisations", "IAMPOLICIES":"Manage ZITADELs global Access policies und elect ZITADEL Managers", @@ -930,12 +961,34 @@ "1": "Active", "2": "Inactive" } + }, + "DIALOG": { + "DELETE": { + "TITLE": "Delete App", + "DESCRIPTION":"Do you really want to delete this application?" + } + }, + "NEXTSTEPS": { + "TITLE":"Next Steps", + "0": { + "TITLE":"Add roles", + "DESC":"Enter your project roles" + }, + "1": { + "TITLE":"Add users", + "DESC":"Add new users of your organization" + }, + "2": { + "TITLE":"Help & Support", + "DESC":"Read our documentation on creating applications or contact our support" + } } }, "NAME": "Name", "TYPE":"Application Type", "GRANT":"Grant Types", "OIDC": { + "CURRENT":"Current Config", "TOKENSECTIONTITLE":"AuthToken Options", "REDIRECTSECTIONTITLE":"Redirect Settings", "PROSWITCH":"I'm a pro. Skip this wizard.", @@ -991,13 +1044,58 @@ "IDTOKENROLEASSERTION_DESCRIPTION":"If selected, the roles of the authenticated user are added to the ID token.", "IDTOKENUSERINFOASSERTION":"User Info inside ID Token", "IDTOKENUSERINFOASSERTION_DESCRIPTION":"Enables clients to retrieve profile, email, phone and address claims from ID token.", - "CLOCKSKEW":"Enables clients to handle clock skew of OP and client. The duration (0-5s) will be added to exp claim and subtracted from iats, auth_time and nbf." + "CLOCKSKEW":"Enables clients to handle clock skew of OP and client. The duration (0-5s) will be added to exp claim and subtracted from iats, auth_time and nbf.", + "RECOMMENDED":"recommended", + "NOTRECOMMENDED":"not recommended", + "SELECTION":{ + "APPTYPE": { + "WEB": { + "TITLE":"Web", + "DESCRIPTION":"Regular Web applications like .net, PHP, Node.js, Java, etc." + }, + "NATIVE": { + "TITLE":"NATIVE", + "DESCRIPTION":"Mobile Apps, Desktop, Smart Devices, etc." + }, + "USERAGENT": { + "TITLE":"User Agent", + "DESCRIPTION":"Single Page Applications (SPA) and in general all JS frameworks executed in browsers" + } + }, + "AUTHMETHOD": { + "CODE": { + "TITLE":"Code", + "DESCRIPTION":"Exchange the authorization code for the tokens" + }, + "PKCE": { + "TITLE":"PKCE", + "DESCRIPTION":"Use a random hash instead of a static client secret for more security" + }, + "POST": { + "TITLE":"POST", + "DESCRIPTION":"Send client_id and client_secret as part of the form" + }, + "PK_JWT": { + "TITLE":"Private Key JWT", + "DESCRIPTION":"Use a private key to authorize your application" + }, + "IMPLICIT": { + "TITLE":"Implicit", + "DESCRIPTION":"Get the tokens directly from the authorization endpoint" + }, + "CUSTOM": { + "TITLE":"Custom", + "DESCRIPTION":"Your setting doesn't correspond to any other option." + } + } + } }, "TOAST": { "REACTIVATED":"Application reactivated.", "DEACTIVATED":"Application deactivated.", "OIDCUPDATED":"OIDC configuration updated.", - "OIDCCLIENTSECRETREGENERATED":"OIDC client secret generated." + "OIDCCLIENTSECRETREGENERATED":"OIDC client secret generated.", + "DELETED":"App deleted." } }, "GENDERS": { diff --git a/console/src/assets/images/zitadel-logo-solo-dark.svg b/console/src/assets/images/zitadel-logo-solo-dark.svg new file mode 100644 index 000000000..4d3181174 --- /dev/null +++ b/console/src/assets/images/zitadel-logo-solo-dark.svg @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/console/src/assets/images/zitadel-logo-solo-light.svg b/console/src/assets/images/zitadel-logo-solo-light.svg new file mode 100644 index 000000000..df44ec539 --- /dev/null +++ b/console/src/assets/images/zitadel-logo-solo-light.svg @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/console/src/component-themes.scss b/console/src/component-themes.scss index 40f16d435..1d814219a 100644 --- a/console/src/component-themes.scss +++ b/console/src/component-themes.scss @@ -5,24 +5,29 @@ @import './styles/link.scss'; @import './styles/sidenav-list'; @import 'src/app/modules/avatar/avatar.component'; +@import 'src/app/modules/app-radio/app-type-radio/app-type-radio.component'; +@import 'src/app/modules/app-radio/app-auth-method-radio/app-auth-method-radio.component'; @import 'src/app/modules/changes/changes.component'; @import 'src/app/modules/info-section/info-section.component'; @import 'src/app/modules/detail-layout/detail-layout.component'; -@import 'src/app/pages/projects/owned-projects/owned-project-detail/application-grid/application-grid.component'; +@import 'src/app/modules/app-card/app-card.component'; @import 'src/app/pages/users/user-detail/auth-user-detail/theme-setting/theme-card'; @import 'src/app/pages/users/user-detail/memberships/memberships.component'; @import 'src/app/app.component.scss'; @import 'src/app/modules/form-field/form-field.component.scss'; @import 'src/app/modules/label/label.component.scss'; @import 'src/app/modules/meta-layout/meta.scss'; +@import 'src/app/modules/onboarding/onboarding.component.scss'; @mixin component-themes($theme) { @include avatar-theme($theme); + @include app-type-radio-theme($theme); + @include app-auth-method-radio-theme($theme); @include card-theme($theme); @include table-theme($theme); @include detail-layout-theme($theme); @include sidenav-list-theme($theme); - @include application-grid-theme($theme); + @include app-card-theme($theme); @include membership-theme($theme); @include changes-theme($theme); @include theme-card($theme); @@ -34,4 +39,5 @@ @include link-theme($theme); @include meta-theme($theme); @include info-section-theme($theme); + @include onboarding-theme($theme); } diff --git a/console/src/styles.scss b/console/src/styles.scss index 3eaff8301..fbe3b6a0c 100644 --- a/console/src/styles.scss +++ b/console/src/styles.scss @@ -219,18 +219,21 @@ $custom-typography: box-shadow: inset 0 0 6px rgba(0, 0, 0, .3); background-color: #2d2e30; border-radius: 8px; + transition: all .3s cubic-bezier(.645, .045, .355, 1) !important; } ::-webkit-scrollbar { width: 6px; height: 6px; background-color: #2d2e30; + transition: all .3s cubic-bezier(.645, .045, .355, 1) !important; } ::-webkit-scrollbar-thumb { background-color: #737c8870; border-radius: 8px; cursor: pointer; + transition: all .3s cubic-bezier(.645, .045, .355, 1) !important; } .root-header { diff --git a/console/src/styles/sidenav-list.scss b/console/src/styles/sidenav-list.scss index baf779d77..fdd8600b8 100644 --- a/console/src/styles/sidenav-list.scss +++ b/console/src/styles/sidenav-list.scss @@ -16,18 +16,23 @@ box-shadow: inset 1px 0 if($is-dark-theme, #303131, #e3e8ee); } + .sidenav { + box-shadow: inset -1px 0 if($is-dark-theme, #303131, #e3e8ee); + transition: all .3s cubic-bezier(.645, .045, .355, 1) !important; + } + .nav-item { color: mat-color($foreground, text) !important; &:hover { - background-color: $sec-dark; + background-color: if($is-dark-theme, $sec-dark, rgb(84 105 212 / 6%)); border-top-right-radius: 1.5rem; border-bottom-right-radius: 1.5rem; } &.active { color: $primary-color !important; - background-color: rgba($color: $primary-color, $alpha: .1) !important; + background-color: if($is-dark-theme, rgba($color: $primary-color, $alpha: .1), rgb(84 105 212 / 6%)) !important; } .c_label { @@ -54,7 +59,16 @@ .root-header { box-shadow: inset 0 -1px #e3e8ee; background-color: $primary-dark !important; - transition: background-color .3s cubic-bezier(.645, .045, .355, 1); + transition: all .3s cubic-bezier(.645, .045, .355, 1); + + .slash { + color: if($is-dark-theme, #525454, #d1d5d9); + } + + .org-button { + border: 1px solid if($is-dark-theme, #303131, #e3e8ee); + transition: all .3s cubic-bezier(.645, .045, .355, 1) !important; + } } .admin-line { @@ -63,7 +77,7 @@ align-items: center; bottom: 0; left: 0; - right: calc(100vw - 300px); + right: calc(100vw - 280px); background-color: $primary-color; color: white; z-index: 1; diff --git a/console/src/styles/table.scss b/console/src/styles/table.scss index a93573050..149a4cb5a 100644 --- a/console/src/styles/table.scss +++ b/console/src/styles/table.scss @@ -64,7 +64,8 @@ } } - .mat-checkbox { + td .mat-checkbox, + th .mat-checkbox { margin-left: 1rem; } diff --git a/go.mod b/go.mod index f1a3c5e37..baa42a005 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/allegro/bigcache v1.2.1 github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc github.com/caos/logging v0.0.2 - github.com/caos/oidc v0.13.2 + github.com/caos/oidc v0.14.0 github.com/caos/orbos v1.5.14-0.20210205131708-6dc812182dc0 github.com/cockroachdb/cockroach-go/v2 v2.1.0 github.com/duo-labs/webauthn v0.0.0-20200714211715-1daaee874e43 @@ -56,7 +56,7 @@ require ( github.com/rs/cors v1.7.0 github.com/sony/sonyflake v1.0.0 github.com/spf13/cobra v0.0.7 - github.com/stretchr/testify v1.6.1 + github.com/stretchr/testify v1.7.0 github.com/ttacon/builder v0.0.0-20170518171403-c099f663e1c2 // indirect github.com/ttacon/libphonenumber v1.1.0 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.13.0 @@ -69,7 +69,7 @@ require ( golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 golang.org/x/net v0.0.0-20201031054903-ff519b6c9102 // indirect golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 // indirect - golang.org/x/text v0.3.4 + golang.org/x/text v0.3.5 golang.org/x/tools v0.0.0-20201103235415-b653051172e4 google.golang.org/api v0.34.0 google.golang.org/appengine v1.6.7 // indirect diff --git a/go.sum b/go.sum index 717321d28..0e642d25f 100644 --- a/go.sum +++ b/go.sum @@ -108,6 +108,7 @@ github.com/allegro/bigcache v1.2.1 h1:hg1sY1raCwic3Vnsvje6TT7/pnZba83LeFck5NrFKS github.com/allegro/bigcache v1.2.1/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= +github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= @@ -116,6 +117,7 @@ github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hC github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= @@ -124,6 +126,7 @@ github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQ github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.31.12/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= +github.com/benbjohnson/clock v1.0.3 h1:vkLuvpK4fmtSCuo60+yC63p7y0BmQ8gm5ZXGuBCJyXg= github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= @@ -137,12 +140,8 @@ github.com/caos/logging v0.0.0-20191210002624-b3260f690a6a/go.mod h1:9LKiDE2ChuG github.com/caos/logging v0.0.2 h1:ebg5C/HN0ludYR+WkvnFjwSExF4wvyiWPyWGcKMYsoo= github.com/caos/logging v0.0.2/go.mod h1:9LKiDE2ChuGv6CHYif/kiugrfEXu9AwDiFWSreX7Wp0= github.com/caos/oidc v0.6.2/go.mod h1:ozoi3b+aY33gzdvjz4w90VZShIHGsmDa0goruuV0arQ= -github.com/caos/oidc v0.13.2 h1:52oP3KB1UrZuwraBTLuwM9ItRIhJQMYOm1J5uQ0sYXw= -github.com/caos/oidc v0.13.2/go.mod h1:dLvfYUiAt9ORfl77L/KkcWuR/N0ll8Ry1nD2ERsamDY= -github.com/caos/orbos v1.5.14-0.20210128140136-842933949472 h1:iti4tAKxBknjJkQcDKWaxlj9Jbng5kz5TpQzzyda49o= -github.com/caos/orbos v1.5.14-0.20210128140136-842933949472/go.mod h1:ZLxNgPuYIlSvr80trezGGUIXng9gY2hHEdky/m0B/P0= -github.com/caos/orbos v1.5.14-0.20210202122121-ad32524ffc73 h1:usYmCT11HvwxBCk1+DSCmEU6CVYhzY8jHaQHSJMrxlg= -github.com/caos/orbos v1.5.14-0.20210202122121-ad32524ffc73/go.mod h1:ZLxNgPuYIlSvr80trezGGUIXng9gY2hHEdky/m0B/P0= +github.com/caos/oidc v0.14.0 h1:l7mTqYDpqNRZF9Vwzq5KAQd1wQCThdceL5HpsEMGoao= +github.com/caos/oidc v0.14.0/go.mod h1:CPsubVrA110OyLnCKwVZjTdsAVwq67DTbYIvux7UgbY= github.com/caos/orbos v1.5.14-0.20210205131708-6dc812182dc0 h1:N+KYBwuQO3QPr/nTUaNwjAetjp3NU4MP8Nv9Iue53UE= github.com/caos/orbos v1.5.14-0.20210205131708-6dc812182dc0/go.mod h1:ZLxNgPuYIlSvr80trezGGUIXng9gY2hHEdky/m0B/P0= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= @@ -154,9 +153,11 @@ github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghf github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw= +github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= @@ -186,13 +187,17 @@ github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfc github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/creack/pty v1.1.7 h1:6pwm8kMQKCmgUg0ZHTm5+/YvRK0s3THD/28+T6/kk4A= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd/go.mod h1:dv4zxwHi5C/8AeI+4gX4dCWOIvNi7I6JCSX0HvlKPgE= +github.com/deckarep/golang-set v1.7.1 h1:SCQV0S6gTtp6itiFrTqI+pfmJ4LN85S1YzhDf9rTHJQ= github.com/deckarep/golang-set v1.7.1/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ= +github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd h1:83Wprp6ROGeiHFAP8WJdI2RoxALQYgdllERc3N5N2DM= github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= @@ -212,6 +217,7 @@ github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5m github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153 h1:yUdfgN0XgIJw7foRItutHYUIhlcKzcSf5vDpdhQAKTc= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= @@ -224,23 +230,28 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DPaBjB8zlTR87/ElzFsnQfuHnVUVqpZZIcV5Y= github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0= +github.com/evanphx/json-patch v4.2.0+incompatible h1:fUDGZCv/7iAN7u0puUVhvKCcsR6vRfwrJatElLBEf0I= github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4= github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ= github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fxamacker/cbor/v2 v2.2.0 h1:6eXqdDDe588rSYAi1HfZKbx6YYQO4mxQ9eC6xYpU/JQ= github.com/fxamacker/cbor/v2 v2.2.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0= github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= @@ -298,6 +309,7 @@ github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+ github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA= github.com/go-openapi/validate v0.19.5/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= @@ -308,6 +320,7 @@ github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -367,8 +380,10 @@ github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0 h1:wCKgOCHuUEVfsaQLpPSJb7VdYCdTVZQAuOdYm1yc/60= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= @@ -383,6 +398,8 @@ github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs= +github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= @@ -390,6 +407,7 @@ github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsC github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.3.1 h1:WeAefnSUHlBb0iJKwxFDZdbfGwkd7xRNuV+IpXMJhYk= github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU= +github.com/googleinterns/cloud-operations-api-mock v0.0.0-20200709193332-a1e58c29bdd3 h1:eHv/jVY/JNop1xg2J9cBb4EzyMpWZoNCP1BslSAIkOI= github.com/googleinterns/cloud-operations-api-mock v0.0.0-20200709193332-a1e58c29bdd3/go.mod h1:h/KNeRx7oYU4SpA4SoY7W2/NxDKEEVuwA6j9A27L4OI= github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= @@ -442,7 +460,9 @@ github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174 h1:WlZsjVhE8Af9IcZDGgJGQpNflI3+MJSBhsgT5PCtzBQ= github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174/go.mod h1:DqJ97dSdRW1W22yXSB90986pcOyQ7r45iio1KN2ez1A= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw= github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= @@ -455,6 +475,7 @@ github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA= github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/inconshreveable/log15 v0.0.0-20200109203555-b30bc20e4fd1 h1:KUDFlmBg2buRWNzIcwLlKvfcnujcHQRQ1As1LoaCLAM= github.com/inconshreveable/log15 v0.0.0-20200109203555-b30bc20e4fd1/go.mod h1:cOaXtrgN4ScfRrD9Bre7U1thNq5RtJ8ZoP4iXVGRj6o= +github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= @@ -510,6 +531,7 @@ github.com/jinzhu/gorm v1.9.16/go.mod h1:G3LB3wezTOWM2ITLzPxEXgSkOXAntiLHS7UdBef github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/jinzhu/now v1.1.1 h1:g39TucaRWyV3dwDO++eEc6qf8TVIQ/Da48WmqjZ3i7E= github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= @@ -523,6 +545,7 @@ github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/u github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a h1:FaWFmfWdAUKbSCtOU2QjDaorUexogfaMgbipgYATUMU= @@ -553,8 +576,11 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.4/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= +github.com/kr/pty v1.1.8 h1:AkaSdXYQOWeaO3neb8EM634ahkXXe3jYbVh/F9lq+GI= github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/landoop/tableprinter v0.0.0-20200805134727-ea32388e35c1/go.mod h1:f0X1c0za3TbET/rl5ThtCSel0+G3/yZ8iuU9BxnyVK0= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= @@ -602,6 +628,7 @@ github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus= +github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U= github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= @@ -644,6 +671,7 @@ github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxzi github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/nicksnyder/go-i18n/v2 v2.1.1 h1:ATCOanRDlrfKVB4WHAdJnLEqZtDmKYsweqsOUYflnBU= github.com/nicksnyder/go-i18n/v2 v2.1.1/go.mod h1:d++QJC9ZVf7pa48qrsRWhMJ5pSHIPmS3OLqK1niyLxs= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= @@ -653,9 +681,11 @@ github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FW github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw= github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= @@ -792,6 +822,8 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= @@ -908,6 +940,7 @@ golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= @@ -1053,6 +1086,8 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1154,6 +1189,7 @@ google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -1231,9 +1267,11 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U= gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= @@ -1246,9 +1284,11 @@ gopkg.in/square/go-jose.v2 v2.5.1 h1:7odma5RETjNHWJnR32wx8t+Io4djHE1PqxCFx3iiZ2w gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/src-d/go-billy.v4 v4.3.2 h1:0SQA1pRztfTFx2miS8sA97XvooFeNOmvUenF4o0EcVg= gopkg.in/src-d/go-billy.v4 v4.3.2/go.mod h1:nDjArDMp+XMs1aFAESLRjfGSgfvoYN0hDfzEk0GjC98= +gopkg.in/src-d/go-git-fixtures.v3 v3.5.0 h1:ivZFOIltbce2Mo8IjzUHAFoq/IylO9WHhNOAJK+LsJg= gopkg.in/src-d/go-git-fixtures.v3 v3.5.0/go.mod h1:dLBcvytrw/TYZsNTWCnkNF2DSIlzWYqTe3rJR56Ac7g= gopkg.in/src-d/go-git.v4 v4.13.1 h1:SRtFyV8Kxc0UP7aCHcijOMQGPxHSmMOPrzulQWolkYE= gopkg.in/src-d/go-git.v4 v4.13.1/go.mod h1:nx5NYcxdKxq5fpltdHnPa2Exj4Sx0EclMWZQbYDu2z8= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= @@ -1301,6 +1341,7 @@ k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUc k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= +k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6 h1:Oh3Mzx5pJ+yIumsAD0MOECPVeXsVot0UkiaCGVyfGQY= k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= k8s.io/kubectl v0.18.3/go.mod h1:k/EpvXBDgEsHBzWr0A44l9+ArvYi3txBBnzXBjQasUQ= k8s.io/metrics v0.18.3/go.mod h1:TkuJE3ezDZ1ym8pYkZoEzJB7HDiFE7qxl+EmExEBoPA= diff --git a/internal/api/authz/context.go b/internal/api/authz/context.go index 62e33421e..63af939e9 100644 --- a/internal/api/authz/context.go +++ b/internal/api/authz/context.go @@ -37,6 +37,27 @@ type Grant struct { Roles []string } +type Memberships []*Membership + +type Membership struct { + MemberType MemberType + AggregateID string + //ObjectID differs from aggregate id if obejct is sub of an aggregate + ObjectID string + + Roles []string +} + +type MemberType int32 + +const ( + MemberTypeUnspecified MemberType = iota + MemberTypeOrganisation + MemberTypeProject + MemberTypeProjectGrant + MemberTypeIam +) + func VerifyTokenAndCreateCtxData(ctx context.Context, token, orgID string, t *TokenVerifier, method string) (_ CtxData, err error) { ctx, span := tracing.NewSpan(ctx) defer func() { span.EndWithError(err) }() diff --git a/internal/api/authz/permissions.go b/internal/api/authz/permissions.go index 6423f80fd..c91eeaef5 100644 --- a/internal/api/authz/permissions.go +++ b/internal/api/authz/permissions.go @@ -2,7 +2,6 @@ package authz import ( "context" - "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/telemetry/tracing" ) @@ -16,41 +15,43 @@ func getUserMethodPermissions(ctx context.Context, t *TokenVerifier, requiredPer } ctx = context.WithValue(ctx, dataKey, ctxData) - grant, err := t.ResolveGrant(ctx) + memberships, err := t.SearchMyMemberships(ctx) if err != nil { return nil, nil, err } - if grant == nil { + if len(memberships) == 0 { return requestedPermissions, nil, nil } - requestedPermissions, allPermissions = mapGrantToPermissions(requiredPerm, grant, authConfig) + requestedPermissions, allPermissions = mapMembershipsToPermissions(requiredPerm, memberships, authConfig) return requestedPermissions, allPermissions, nil } -func mapGrantToPermissions(requiredPerm string, grant *Grant, authConfig Config) (requestPermissions, allPermissions []string) { +func mapMembershipsToPermissions(requiredPerm string, memberships []*Membership, authConfig Config) (requestPermissions, allPermissions []string) { requestPermissions = make([]string, 0) allPermissions = make([]string, 0) - for _, role := range grant.Roles { - requestPermissions, allPermissions = mapRoleToPerm(requiredPerm, role, authConfig, requestPermissions, allPermissions) + for _, membership := range memberships { + requestPermissions, allPermissions = mapMembershipToPerm(requiredPerm, membership, authConfig, requestPermissions, allPermissions) } return requestPermissions, allPermissions } -func mapRoleToPerm(requiredPerm, actualRole string, authConfig Config, requestPermissions, allPermissions []string) ([]string, []string) { - roleName, roleContextID := SplitPermission(actualRole) - perms := authConfig.getPermissionsFromRole(roleName) +func mapMembershipToPerm(requiredPerm string, membership *Membership, authConfig Config, requestPermissions, allPermissions []string) ([]string, []string) { + roleNames, roleContextID := roleWithContext(membership) + for _, roleName := range roleNames { + perms := authConfig.getPermissionsFromRole(roleName) - for _, p := range perms { - permWithCtx := addRoleContextIDToPerm(p, roleContextID) - if !ExistsPerm(allPermissions, permWithCtx) { - allPermissions = append(allPermissions, permWithCtx) - } + for _, p := range perms { + permWithCtx := addRoleContextIDToPerm(p, roleContextID) + if !ExistsPerm(allPermissions, permWithCtx) { + allPermissions = append(allPermissions, permWithCtx) + } - p, _ = SplitPermission(p) - if p == requiredPerm { - if !ExistsPerm(requestPermissions, permWithCtx) { - requestPermissions = append(requestPermissions, permWithCtx) + p, _ = SplitPermission(p) + if p == requiredPerm { + if !ExistsPerm(requestPermissions, permWithCtx) { + requestPermissions = append(requestPermissions, permWithCtx) + } } } } @@ -72,3 +73,10 @@ func ExistsPerm(existingPermissions []string, perm string) bool { } return false } + +func roleWithContext(membership *Membership) (roles []string, ctxID string) { + if membership.MemberType == MemberTypeProject || membership.MemberType == MemberTypeProjectGrant { + return membership.Roles, membership.ObjectID + } + return membership.Roles, "" +} diff --git a/internal/api/authz/permissions_test.go b/internal/api/authz/permissions_test.go index eed375bdf..26bdd9805 100644 --- a/internal/api/authz/permissions_test.go +++ b/internal/api/authz/permissions_test.go @@ -12,15 +12,14 @@ func getTestCtx(userID, orgID string) context.Context { } type testVerifier struct { - grant *Grant + memberships []*Membership } func (v *testVerifier) VerifyAccessToken(ctx context.Context, token, clientID string) (string, string, string, string, error) { return "userID", "agentID", "de", "orgID", nil } - -func (v *testVerifier) ResolveGrants(ctx context.Context) (*Grant, error) { - return v.grant, nil +func (v *testVerifier) SearchMyMemberships(ctx context.Context) ([]*Membership, error) { + return v.memberships, nil } func (v *testVerifier) ProjectIDAndOriginsByClientID(ctx context.Context, clientID string) (string, []string, error) { @@ -65,8 +64,10 @@ func Test_GetUserMethodPermissions(t *testing.T) { name: "Empty Context", args: args{ ctxData: CtxData{}, - verifier: Start(&testVerifier{grant: &Grant{ - Roles: []string{"ORG_OWNER"}, + verifier: Start(&testVerifier{memberships: []*Membership{ + { + Roles: []string{"ORG_OWNER"}, + }, }}), requiredPerm: "project.read", authConfig: Config{ @@ -90,7 +91,7 @@ func Test_GetUserMethodPermissions(t *testing.T) { name: "No Grants", args: args{ ctxData: CtxData{}, - verifier: Start(&testVerifier{grant: &Grant{}}), + verifier: Start(&testVerifier{memberships: []*Membership{}}), requiredPerm: "project.read", authConfig: Config{ RolePermissionMappings: []RoleMapping{ @@ -111,8 +112,13 @@ func Test_GetUserMethodPermissions(t *testing.T) { name: "Get Permissions", args: args{ ctxData: CtxData{UserID: "userID", OrgID: "orgID"}, - verifier: Start(&testVerifier{grant: &Grant{ - Roles: []string{"IAM_OWNER"}, + verifier: Start(&testVerifier{memberships: []*Membership{ + { + AggregateID: "IAM", + ObjectID: "IAM", + MemberType: MemberTypeIam, + Roles: []string{"IAM_OWNER"}, + }, }}), requiredPerm: "project.read", authConfig: Config{ @@ -150,10 +156,10 @@ func Test_GetUserMethodPermissions(t *testing.T) { } } -func Test_MapGrantsToPermissions(t *testing.T) { +func Test_MapMembershipToPermissions(t *testing.T) { type args struct { requiredPerm string - grant *Grant + membership []*Membership authConfig Config } tests := []struct { @@ -166,7 +172,14 @@ func Test_MapGrantsToPermissions(t *testing.T) { name: "One Role existing perm", args: args{ requiredPerm: "project.read", - grant: &Grant{Roles: []string{"ORG_OWNER"}}, + membership: []*Membership{ + { + AggregateID: "1", + ObjectID: "1", + MemberType: MemberTypeOrganisation, + Roles: []string{"ORG_OWNER"}, + }, + }, authConfig: Config{ RolePermissionMappings: []RoleMapping{ { @@ -187,7 +200,14 @@ func Test_MapGrantsToPermissions(t *testing.T) { name: "One Role not existing perm", args: args{ requiredPerm: "project.write", - grant: &Grant{Roles: []string{"ORG_OWNER"}}, + membership: []*Membership{ + { + AggregateID: "1", + ObjectID: "1", + MemberType: MemberTypeOrganisation, + Roles: []string{"ORG_OWNER"}, + }, + }, authConfig: Config{ RolePermissionMappings: []RoleMapping{ { @@ -208,7 +228,20 @@ func Test_MapGrantsToPermissions(t *testing.T) { name: "Multiple Roles one existing", args: args{ requiredPerm: "project.read", - grant: &Grant{Roles: []string{"ORG_OWNER", "IAM_OWNER"}}, + membership: []*Membership{ + { + AggregateID: "1", + ObjectID: "1", + MemberType: MemberTypeOrganisation, + Roles: []string{"ORG_OWNER"}, + }, + { + AggregateID: "IAM", + ObjectID: "IAM", + MemberType: MemberTypeIam, + Roles: []string{"IAM_OWNER"}, + }, + }, authConfig: Config{ RolePermissionMappings: []RoleMapping{ { @@ -229,7 +262,20 @@ func Test_MapGrantsToPermissions(t *testing.T) { name: "Multiple Roles, global and specific", args: args{ requiredPerm: "project.read", - grant: &Grant{Roles: []string{"ORG_OWNER", "PROJECT_OWNER:1"}}, + membership: []*Membership{ + { + AggregateID: "2", + ObjectID: "2", + MemberType: MemberTypeOrganisation, + Roles: []string{"ORG_OWNER"}, + }, + { + AggregateID: "1", + ObjectID: "1", + MemberType: MemberTypeProject, + Roles: []string{"PROJECT_OWNER"}, + }, + }, authConfig: Config{ RolePermissionMappings: []RoleMapping{ { @@ -249,7 +295,7 @@ func Test_MapGrantsToPermissions(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - requestPerms, allPerms := mapGrantToPermissions(tt.args.requiredPerm, tt.args.grant, tt.args.authConfig) + requestPerms, allPerms := mapMembershipsToPermissions(tt.args.requiredPerm, tt.args.membership, tt.args.authConfig) if !equalStringArray(requestPerms, tt.requestPerms) { t.Errorf("got wrong requestPerms, expecting: %v, actual: %v ", tt.requestPerms, requestPerms) } @@ -260,10 +306,10 @@ func Test_MapGrantsToPermissions(t *testing.T) { } } -func Test_MapRoleToPerm(t *testing.T) { +func Test_MapMembershipToPerm(t *testing.T) { type args struct { requiredPerm string - actualRole string + membership *Membership authConfig Config requestPerms []string allPerms []string @@ -278,7 +324,12 @@ func Test_MapRoleToPerm(t *testing.T) { name: "first perm without context id", args: args{ requiredPerm: "project.read", - actualRole: "ORG_OWNER", + membership: &Membership{ + AggregateID: "Org", + ObjectID: "Org", + MemberType: MemberTypeOrganisation, + Roles: []string{"ORG_OWNER"}, + }, authConfig: Config{ RolePermissionMappings: []RoleMapping{ { @@ -301,7 +352,12 @@ func Test_MapRoleToPerm(t *testing.T) { name: "existing perm without context id", args: args{ requiredPerm: "project.read", - actualRole: "ORG_OWNER", + membership: &Membership{ + AggregateID: "Org", + ObjectID: "Org", + MemberType: MemberTypeOrganisation, + Roles: []string{"ORG_OWNER"}, + }, authConfig: Config{ RolePermissionMappings: []RoleMapping{ { @@ -324,7 +380,12 @@ func Test_MapRoleToPerm(t *testing.T) { name: "first perm with context id", args: args{ requiredPerm: "project.read", - actualRole: "PROJECT_OWNER:1", + membership: &Membership{ + AggregateID: "1", + ObjectID: "1", + MemberType: MemberTypeProject, + Roles: []string{"PROJECT_OWNER"}, + }, authConfig: Config{ RolePermissionMappings: []RoleMapping{ { @@ -347,7 +408,12 @@ func Test_MapRoleToPerm(t *testing.T) { name: "perm with context id, existing global", args: args{ requiredPerm: "project.read", - actualRole: "PROJECT_OWNER:1", + membership: &Membership{ + AggregateID: "1", + ObjectID: "1", + MemberType: MemberTypeProject, + Roles: []string{"PROJECT_OWNER"}, + }, authConfig: Config{ RolePermissionMappings: []RoleMapping{ { @@ -369,7 +435,7 @@ func Test_MapRoleToPerm(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - requestPerms, allPerms := mapRoleToPerm(tt.args.requiredPerm, tt.args.actualRole, tt.args.authConfig, tt.args.requestPerms, tt.args.allPerms) + requestPerms, allPerms := mapMembershipToPerm(tt.args.requiredPerm, tt.args.membership, tt.args.authConfig, tt.args.requestPerms, tt.args.allPerms) if !equalStringArray(requestPerms, tt.requestPerms) { t.Errorf("got wrong requestPerms, expecting: %v, actual: %v ", tt.requestPerms, requestPerms) } diff --git a/internal/api/authz/token.go b/internal/api/authz/token.go index 352bb44c5..aacba6bba 100644 --- a/internal/api/authz/token.go +++ b/internal/api/authz/token.go @@ -22,7 +22,7 @@ type TokenVerifier struct { type authZRepo interface { VerifyAccessToken(ctx context.Context, token, clientID string) (userID, agentID, prefLang, resourceOwner string, err error) VerifierClientID(ctx context.Context, name string) (clientID string, err error) - ResolveGrants(ctx context.Context) (grant *Grant, err error) + SearchMyMemberships(ctx context.Context) ([]*Membership, error) ProjectIDAndOriginsByClientID(ctx context.Context, clientID string) (projectID string, origins []string, err error) ExistsOrg(ctx context.Context, orgID string) error } @@ -86,11 +86,10 @@ func (v *TokenVerifier) clientIDFromMethod(ctx context.Context, method string) ( v.clients.Store(prefix, c) return c.id, nil } - -func (v *TokenVerifier) ResolveGrant(ctx context.Context) (_ *Grant, err error) { +func (v *TokenVerifier) SearchMyMemberships(ctx context.Context) (_ []*Membership, err error) { ctx, span := tracing.NewSpan(ctx) defer func() { span.EndWithError(err) }() - return v.authZRepo.ResolveGrants(ctx) + return v.authZRepo.SearchMyMemberships(ctx) } func (v *TokenVerifier) ProjectIDAndOriginsByClientID(ctx context.Context, clientID string) (_ string, _ []string, err error) { diff --git a/internal/api/authz/token_test.go b/internal/api/authz/token_test.go index 7c256086f..c6a54039a 100644 --- a/internal/api/authz/token_test.go +++ b/internal/api/authz/token_test.go @@ -43,7 +43,7 @@ func Test_VerifyAccessToken(t *testing.T) { ctx: context.Background(), token: "Bearer AUTH", verifier: &TokenVerifier{ - authZRepo: &testVerifier{grant: &Grant{}}, + authZRepo: &testVerifier{memberships: []*Membership{}}, clients: func() sync.Map { m := sync.Map{} m.Store("service", &client{name: "name"}) diff --git a/internal/api/grpc/auth/user.go b/internal/api/grpc/auth/user.go index f51a06d5a..7aee2371c 100644 --- a/internal/api/grpc/auth/user.go +++ b/internal/api/grpc/auth/user.go @@ -229,3 +229,13 @@ func (s *Server) GetMyUserChanges(ctx context.Context, request *auth.ChangesRequ } return userChangesToResponse(changes, request.GetSequenceOffset(), request.GetLimit()), nil } + +func (s *Server) SearchMyUserMemberships(ctx context.Context, in *auth.UserMembershipSearchRequest) (*auth.UserMembershipSearchResponse, error) { + request := userMembershipSearchRequestsToModel(in) + request.AppendUserIDQuery(authz.GetCtxData(ctx).UserID) + response, err := s.repo.SearchMyUserMemberships(ctx, request) + if err != nil { + return nil, err + } + return userMembershipSearchResponseFromModel(response), nil +} diff --git a/internal/api/grpc/auth/user_converter.go b/internal/api/grpc/auth/user_converter.go index 07f6302c4..adb1f5358 100644 --- a/internal/api/grpc/auth/user_converter.go +++ b/internal/api/grpc/auth/user_converter.go @@ -3,7 +3,6 @@ package auth import ( "context" "encoding/json" - "github.com/caos/logging" "github.com/golang/protobuf/ptypes" "golang.org/x/text/language" @@ -462,3 +461,93 @@ func ctxToObjectRoot(ctx context.Context) models.ObjectRoot { ResourceOwner: ctxData.ResourceOwner, } } + +func userMembershipSearchResponseFromModel(response *usr_model.UserMembershipSearchResponse) *auth.UserMembershipSearchResponse { + timestamp, err := ptypes.TimestampProto(response.Timestamp) + logging.Log("GRPC-Hs8jd").OnError(err).Debug("unable to parse timestamp") + return &auth.UserMembershipSearchResponse{ + Offset: response.Offset, + Limit: response.Limit, + TotalResult: response.TotalResult, + Result: userMembershipViewsFromModel(response.Result), + ProcessedSequence: response.Sequence, + ViewTimestamp: timestamp, + } +} + +func userMembershipViewsFromModel(memberships []*usr_model.UserMembershipView) []*auth.UserMembershipView { + converted := make([]*auth.UserMembershipView, len(memberships)) + for i, membership := range memberships { + converted[i] = userMembershipViewFromModel(membership) + } + return converted +} + +func userMembershipViewFromModel(membership *usr_model.UserMembershipView) *auth.UserMembershipView { + creationDate, err := ptypes.TimestampProto(membership.CreationDate) + logging.Log("GRPC-Msnu8").OnError(err).Debug("unable to parse timestamp") + + changeDate, err := ptypes.TimestampProto(membership.ChangeDate) + logging.Log("GRPC-Slco9").OnError(err).Debug("unable to parse timestamp") + + return &auth.UserMembershipView{ + UserId: membership.UserID, + AggregateId: membership.AggregateID, + ObjectId: membership.ObjectID, + MemberType: memberTypeFromModel(membership.MemberType), + DisplayName: membership.DisplayName, + Roles: membership.Roles, + CreationDate: creationDate, + ChangeDate: changeDate, + Sequence: membership.Sequence, + ResourceOwner: membership.ResourceOwner, + } +} + +func userMembershipSearchRequestsToModel(request *auth.UserMembershipSearchRequest) *usr_model.UserMembershipSearchRequest { + return &usr_model.UserMembershipSearchRequest{ + Offset: request.Offset, + Limit: request.Limit, + Queries: userMembershipSearchQueriesToModel(request.Queries), + } +} + +func userMembershipSearchQueriesToModel(queries []*auth.UserMembershipSearchQuery) []*usr_model.UserMembershipSearchQuery { + converted := make([]*usr_model.UserMembershipSearchQuery, len(queries)) + for i, q := range queries { + converted[i] = userMembershipSearchQueryToModel(q) + } + return converted +} + +func userMembershipSearchQueryToModel(query *auth.UserMembershipSearchQuery) *usr_model.UserMembershipSearchQuery { + return &usr_model.UserMembershipSearchQuery{ + Key: userMembershipSearchKeyToModel(query.Key), + Method: searchMethodToModel(query.Method), + Value: query.Value, + } +} + +func userMembershipSearchKeyToModel(key auth.UserMembershipSearchKey) usr_model.UserMembershipSearchKey { + switch key { + case auth.UserMembershipSearchKey_USERMEMBERSHIPSEARCHKEY_TYPE: + return usr_model.UserMembershipSearchKeyMemberType + case auth.UserMembershipSearchKey_USERMEMBERSHIPSEARCHKEY_OBJECT_ID: + return usr_model.UserMembershipSearchKeyObjectID + default: + return usr_model.UserMembershipSearchKeyUnspecified + } +} + +func memberTypeFromModel(memberType usr_model.MemberType) auth.MemberType { + switch memberType { + case usr_model.MemberTypeOrganisation: + return auth.MemberType_MEMBERTYPE_ORGANISATION + case usr_model.MemberTypeProject: + return auth.MemberType_MEMBERTYPE_PROJECT + case usr_model.MemberTypeProjectGrant: + return auth.MemberType_MEMBERTYPE_PROJECT_GRANT + default: + return auth.MemberType_MEMBERTYPE_UNSPECIFIED + } +} diff --git a/internal/api/grpc/auth/user_human_converter.go b/internal/api/grpc/auth/user_human_converter.go index e3e077001..7d292a945 100644 --- a/internal/api/grpc/auth/user_human_converter.go +++ b/internal/api/grpc/auth/user_human_converter.go @@ -3,7 +3,7 @@ package auth import ( "github.com/caos/logging" usr_model "github.com/caos/zitadel/internal/user/model" - auth "github.com/caos/zitadel/pkg/grpc/auth" + "github.com/caos/zitadel/pkg/grpc/auth" "github.com/golang/protobuf/ptypes" ) diff --git a/internal/api/grpc/auth/user_machine_converter.go b/internal/api/grpc/auth/user_machine_converter.go index b868354d3..003c0eee1 100644 --- a/internal/api/grpc/auth/user_machine_converter.go +++ b/internal/api/grpc/auth/user_machine_converter.go @@ -2,9 +2,10 @@ package auth import ( "github.com/caos/logging" + "github.com/golang/protobuf/ptypes" + usr_model "github.com/caos/zitadel/internal/user/model" "github.com/caos/zitadel/pkg/grpc/auth" - "github.com/golang/protobuf/ptypes" ) func machineViewFromModel(machine *usr_model.MachineView) *auth.MachineView { @@ -16,36 +17,3 @@ func machineViewFromModel(machine *usr_model.MachineView) *auth.MachineView { LastKeyAdded: lastKeyAdded, } } - -func machineKeyViewsFromModel(keys ...*usr_model.MachineKeyView) []*auth.MachineKeyView { - keyViews := make([]*auth.MachineKeyView, len(keys)) - for i, key := range keys { - keyViews[i] = machineKeyViewFromModel(key) - } - return keyViews -} - -func machineKeyViewFromModel(key *usr_model.MachineKeyView) *auth.MachineKeyView { - creationDate, err := ptypes.TimestampProto(key.CreationDate) - logging.Log("MANAG-gluk7").OnError(err).Debug("unable to parse timestamp") - - expirationDate, err := ptypes.TimestampProto(key.CreationDate) - logging.Log("MANAG-gluk7").OnError(err).Debug("unable to parse timestamp") - - return &auth.MachineKeyView{ - Id: key.ID, - CreationDate: creationDate, - ExpirationDate: expirationDate, - Sequence: key.Sequence, - Type: machineKeyTypeFromModel(key.Type), - } -} - -func machineKeyTypeFromModel(typ usr_model.MachineKeyType) auth.MachineKeyType { - switch typ { - case usr_model.MachineKeyTypeJSON: - return auth.MachineKeyType_MACHINEKEY_JSON - default: - return auth.MachineKeyType_MACHINEKEY_UNSPECIFIED - } -} diff --git a/internal/api/grpc/management/application.go b/internal/api/grpc/management/application.go index f7a6d3575..6e0bc7293 100644 --- a/internal/api/grpc/management/application.go +++ b/internal/api/grpc/management/application.go @@ -32,6 +32,13 @@ func (s *Server) CreateOIDCApplication(ctx context.Context, in *management.OIDCA } return oidcAppFromDomain(app), nil } +func (s *Server) CreateAPIApplication(ctx context.Context, in *management.APIApplicationCreate) (*management.Application, error) { + app, err := s.project.AddApplication(ctx, apiAppCreateToModel(in)) + if err != nil { + return nil, err + } + return appFromModel(app), nil +} func (s *Server) UpdateApplication(ctx context.Context, in *management.ApplicationUpdate) (*management.Application, error) { app, err := s.command.ChangeApplication(ctx, in.ProjectId, appUpdateToDomain(in), authz.GetCtxData(ctx).OrgID) if err != nil { @@ -61,6 +68,14 @@ func (s *Server) UpdateApplicationOIDCConfig(ctx context.Context, in *management return oidcConfigFromDomain(config), nil } +func (s *Server) UpdateApplicationAPIConfig(ctx context.Context, in *management.APIConfigUpdate) (*management.APIConfig, error) { + config, err := s.project.ChangeAPIConfig(ctx, apiConfigUpdateToModel(in)) + if err != nil { + return nil, err + } + return apiConfigFromModel(config), nil +} + func (s *Server) RegenerateOIDCClientSecret(ctx context.Context, in *management.ApplicationID) (*management.ClientSecret, error) { config, err := s.command.ChangeOIDCApplicationSecret(ctx, in.ProjectId, in.Id, authz.GetCtxData(ctx).ResourceOwner) if err != nil { @@ -69,6 +84,14 @@ func (s *Server) RegenerateOIDCClientSecret(ctx context.Context, in *management. return &management.ClientSecret{ClientSecret: config.ClientSecretString}, nil } +func (s *Server) RegenerateAPIClientSecret(ctx context.Context, in *management.ApplicationID) (*management.ClientSecret, error) { + config, err := s.project.ChangeAPIConfigSecret(ctx, in.ProjectId, in.Id) + if err != nil { + return nil, err + } + return &management.ClientSecret{ClientSecret: config.ClientSecretString}, nil +} + func (s *Server) ApplicationChanges(ctx context.Context, changesRequest *management.ChangeRequest) (*management.Changes, error) { response, err := s.project.ApplicationChanges(ctx, changesRequest.Id, changesRequest.SecId, changesRequest.SequenceOffset, changesRequest.Limit, changesRequest.Asc) if err != nil { @@ -76,3 +99,32 @@ func (s *Server) ApplicationChanges(ctx context.Context, changesRequest *managem } return appChangesToResponse(response, changesRequest.GetSequenceOffset(), changesRequest.GetLimit()), nil } + +func (s *Server) SearchClientKeys(ctx context.Context, req *management.ClientKeySearchRequest) (*management.ClientKeySearchResponse, error) { + result, err := s.project.SearchClientKeys(ctx, clientKeySearchRequestToModel(req)) + if err != nil { + return nil, err + } + return clientKeySearchResponseFromModel(result), nil +} + +func (s *Server) GetClientKey(ctx context.Context, req *management.ClientKeyIDRequest) (*management.ClientKeyView, error) { + key, err := s.project.GetClientKey(ctx, req.ProjectId, req.ApplicationId, req.KeyId) + if err != nil { + return nil, err + } + return clientKeyViewFromModel(key), nil +} + +func (s *Server) AddClientKey(ctx context.Context, req *management.AddClientKeyRequest) (*management.AddClientKeyResponse, error) { + key, err := s.project.AddClientKey(ctx, addClientKeyToModel(req)) + if err != nil { + return nil, err + } + return addClientKeyFromModel(key), nil +} + +func (s *Server) DeleteClientKey(ctx context.Context, req *management.ClientKeyIDRequest) (*empty.Empty, error) { + err := s.project.RemoveClientKey(ctx, req.ProjectId, req.ApplicationId, req.KeyId) + return &empty.Empty{}, err +} diff --git a/internal/api/grpc/management/application_converter.go b/internal/api/grpc/management/application_converter.go index 639c27014..2c0cc243a 100644 --- a/internal/api/grpc/management/application_converter.go +++ b/internal/api/grpc/management/application_converter.go @@ -2,18 +2,20 @@ package management import ( "encoding/json" - "github.com/caos/zitadel/internal/v2/domain" - "google.golang.org/protobuf/types/known/timestamppb" + "time" "github.com/caos/logging" "github.com/golang/protobuf/ptypes" "google.golang.org/protobuf/encoding/protojson" "google.golang.org/protobuf/types/known/durationpb" "google.golang.org/protobuf/types/known/structpb" + "google.golang.org/protobuf/types/known/timestamppb" "github.com/caos/zitadel/internal/eventstore/models" + key_model "github.com/caos/zitadel/internal/key/model" "github.com/caos/zitadel/internal/model" proj_model "github.com/caos/zitadel/internal/project/model" + "github.com/caos/zitadel/internal/v2/domain" "github.com/caos/zitadel/pkg/grpc/management" "github.com/caos/zitadel/pkg/grpc/message" ) @@ -25,6 +27,28 @@ func appFromDomain(app domain.Application) *management.Application { Name: app.GetApplicationName(), } } +func appFromModel(app *proj_model.Application) *management.Application { + changeDate, err := ptypes.TimestampProto(app.ChangeDate) + logging.Log("GRPC-di7rw").OnError(err).Debug("unable to parse timestamp") + + return &management.Application{ + Id: app.AppID, + State: appStateFromModel(app.State), + ChangeDate: changeDate, + Name: app.Name, + Sequence: app.Sequence, + AppConfig: appConfigFromModel(app), + } +} + +func appConfigFromModel(app *proj_model.Application) management.AppConfig { + if app.Type == proj_model.AppTypeAPI { + return &management.Application_ApiConfig{ + ApiConfig: apiConfigFromModel(app.APIConfig), + } + } + return nil +} func oidcAppFromDomain(app *domain.OIDCApp) *management.Application { return &management.Application{ @@ -41,6 +65,7 @@ func oidcAppConfigFromDomain(app *domain.OIDCApp) management.AppConfig { return &management.Application_OidcConfig{ OidcConfig: oidcConfigFromDomain(app), } + return nil } func oidcConfigFromDomain(config *domain.OIDCApp) *management.OIDCConfig { @@ -65,6 +90,14 @@ func oidcConfigFromDomain(config *domain.OIDCApp) *management.OIDCConfig { } } +func apiConfigFromModel(config *proj_model.APIConfig) *management.APIConfig { + return &management.APIConfig{ + ClientId: config.ClientID, + ClientSecret: config.ClientSecretString, + AuthMethodType: apiAuthMethodTypeFromModel(config.AuthMethodType), + } +} + func oidcConfigFromApplicationViewModel(app *proj_model.ApplicationView) *management.OIDCConfig { return &management.OIDCConfig{ RedirectUris: app.OIDCRedirectUris, @@ -74,11 +107,11 @@ func oidcConfigFromApplicationViewModel(app *proj_model.ApplicationView) *manage ClientId: app.OIDCClientID, AuthMethodType: oidcAuthMethodTypeFromModel(app.OIDCAuthMethodType), PostLogoutRedirectUris: app.OIDCPostLogoutRedirectUris, - Version: oidcVersionFromModel(app.OIDCVersion), + Version: oidcVersionFromDomain(domain.OIDCVersion(app.OIDCVersion)), NoneCompliant: app.NoneCompliant, ComplianceProblems: complianceProblemsToLocalizedMessages(app.ComplianceProblems), DevMode: app.DevMode, - AccessTokenType: oidcTokenTypeFromModel(app.AccessTokenType), + AccessTokenType: oidcTokenTypeFromDomain(domain.OIDCTokenType(app.AccessTokenType)), AccessTokenRoleAssertion: app.AccessTokenRoleAssertion, IdTokenRoleAssertion: app.IDTokenRoleAssertion, IdTokenUserinfoAssertion: app.IDTokenUserinfoAssertion, @@ -124,6 +157,29 @@ func appUpdateToDomain(app *management.ApplicationUpdate) domain.Application { } } +func apiAppCreateToModel(app *management.APIApplicationCreate) *proj_model.Application { + return &proj_model.Application{ + ObjectRoot: models.ObjectRoot{ + AggregateID: app.ProjectId, + }, + Name: app.Name, + Type: proj_model.AppTypeAPI, + APIConfig: &proj_model.APIConfig{ + AuthMethodType: apiAuthMethodTypeToModel(app.AuthMethodType), + }, + } +} + +func appUpdateToModel(app *management.ApplicationUpdate) *proj_model.Application { + return &proj_model.Application{ + ObjectRoot: models.ObjectRoot{ + AggregateID: app.ProjectId, + }, + AppID: app.Id, + Name: app.Name, + } +} + func oidcConfigUpdateToDomain(app *management.OIDCConfigUpdate) *domain.OIDCApp { return &domain.OIDCApp{ ObjectRoot: models.ObjectRoot{ @@ -145,6 +201,16 @@ func oidcConfigUpdateToDomain(app *management.OIDCConfigUpdate) *domain.OIDCApp } } +func apiConfigUpdateToModel(app *management.APIConfigUpdate) *proj_model.APIConfig { + return &proj_model.APIConfig{ + ObjectRoot: models.ObjectRoot{ + AggregateID: app.ProjectId, + }, + AppID: app.ApplicationId, + AuthMethodType: apiAuthMethodTypeToModel(app.AuthMethodType), + } +} + func applicationSearchRequestsToModel(request *management.ApplicationSearchRequest) *proj_model.ApplicationSearchRequest { return &proj_model.ApplicationSearchRequest{ Offset: request.Offset, @@ -404,6 +470,8 @@ func oidcAuthMethodTypeToDomain(authType management.OIDCAuthMethodType) domain.O return domain.OIDCAuthMethodTypePost case management.OIDCAuthMethodType_OIDCAUTHMETHODTYPE_NONE: return domain.OIDCAuthMethodTypeNone + case management.OIDCAuthMethodType_OIDCAUTHMETHODTYPE_PRIVATE_KEY_JWT: + return domain.OIDCAuthMethodTypePrivateKeyJWT default: return domain.OIDCAuthMethodTypeBasic } @@ -422,6 +490,17 @@ func oidcAuthMethodTypeFromDomain(authType domain.OIDCAuthMethodType) management } } +func apiAuthMethodTypeToModel(authType management.APIAuthMethodType) proj_model.APIAuthMethodType { + switch authType { + case management.APIAuthMethodType_APIAUTHMETHODTYPE_BASIC: + return proj_model.APIAuthMethodTypeBasic + case management.APIAuthMethodType_APIAUTHMETHODTYPE_PRIVATE_KEY_JWT: + return proj_model.APIAuthMethodTypePrivateKeyJWT + default: + return proj_model.APIAuthMethodTypeBasic + } +} + func oidcAuthMethodTypeFromModel(authType proj_model.OIDCAuthMethodType) management.OIDCAuthMethodType { switch authType { case proj_model.OIDCAuthMethodTypeBasic: @@ -430,6 +509,8 @@ func oidcAuthMethodTypeFromModel(authType proj_model.OIDCAuthMethodType) managem return management.OIDCAuthMethodType_OIDCAUTHMETHODTYPE_POST case proj_model.OIDCAuthMethodTypeNone: return management.OIDCAuthMethodType_OIDCAUTHMETHODTYPE_NONE + case proj_model.OIDCAuthMethodTypePrivateKeyJWT: + return management.OIDCAuthMethodType_OIDCAUTHMETHODTYPE_PRIVATE_KEY_JWT default: return management.OIDCAuthMethodType_OIDCAUTHMETHODTYPE_BASIC } @@ -457,14 +538,14 @@ func oidcTokenTypeFromDomain(tokenType domain.OIDCTokenType) management.OIDCToke } } -func oidcTokenTypeFromModel(tokenType proj_model.OIDCTokenType) management.OIDCTokenType { - switch tokenType { - case proj_model.OIDCTokenTypeBearer: - return management.OIDCTokenType_OIDCTokenType_Bearer - case proj_model.OIDCTokenTypeJWT: - return management.OIDCTokenType_OIDCTokenType_JWT +func apiAuthMethodTypeFromModel(authType proj_model.APIAuthMethodType) management.APIAuthMethodType { + switch authType { + case proj_model.APIAuthMethodTypeBasic: + return management.APIAuthMethodType_APIAUTHMETHODTYPE_BASIC + case proj_model.APIAuthMethodTypePrivateKeyJWT: + return management.APIAuthMethodType_APIAUTHMETHODTYPE_PRIVATE_KEY_JWT default: - return management.OIDCTokenType_OIDCTokenType_Bearer + return management.APIAuthMethodType_APIAUTHMETHODTYPE_BASIC } } @@ -477,15 +558,6 @@ func oidcVersionFromDomain(version domain.OIDCVersion) management.OIDCVersion { } } -func oidcVersionFromModel(version proj_model.OIDCVersion) management.OIDCVersion { - switch version { - case proj_model.OIDCVersionV1: - return management.OIDCVersion_OIDCV1_0 - default: - return management.OIDCVersion_OIDCV1_0 - } -} - func appChangesToResponse(response *proj_model.ApplicationChanges, offset uint64, limit uint64) (_ *management.Changes) { return &management.Changes{ Limit: limit, @@ -515,3 +587,126 @@ func appChangesToMgtAPI(changes *proj_model.ApplicationChanges) (_ []*management return result } + +func clientKeyViewsFromModel(keys ...*key_model.AuthNKeyView) []*management.ClientKeyView { + keyViews := make([]*management.ClientKeyView, len(keys)) + for i, key := range keys { + keyViews[i] = clientKeyViewFromModel(key) + } + return keyViews +} + +func clientKeyViewFromModel(key *key_model.AuthNKeyView) *management.ClientKeyView { + creationDate, err := ptypes.TimestampProto(key.CreationDate) + logging.Log("MANAG-DAs2t").OnError(err).Debug("unable to parse timestamp") + + expirationDate, err := ptypes.TimestampProto(key.ExpirationDate) + logging.Log("MANAG-BDgh4").OnError(err).Debug("unable to parse timestamp") + + return &management.ClientKeyView{ + Id: key.ID, + CreationDate: creationDate, + ExpirationDate: expirationDate, + Sequence: key.Sequence, + Type: authNKeyTypeFromModel(key.Type), + } +} + +func addClientKeyToModel(key *management.AddClientKeyRequest) *proj_model.ClientKey { + expirationDate := time.Time{} + if key.ExpirationDate != nil { + var err error + expirationDate, err = ptypes.Timestamp(key.ExpirationDate) + logging.Log("MANAG-Dgt42").OnError(err).Debug("unable to parse expiration date") + } + + return &proj_model.ClientKey{ + ExpirationDate: expirationDate, + Type: authNKeyTypeToModel(key.Type), + ApplicationID: key.ApplicationId, + ObjectRoot: models.ObjectRoot{AggregateID: key.ProjectId}, + } +} + +func addClientKeyFromModel(key *proj_model.ClientKey) *management.AddClientKeyResponse { + creationDate, err := ptypes.TimestampProto(key.CreationDate) + logging.Log("MANAG-FBzz4").OnError(err).Debug("unable to parse cretaion date") + + expirationDate, err := ptypes.TimestampProto(key.ExpirationDate) + logging.Log("MANAG-sag21").OnError(err).Debug("unable to parse cretaion date") + + detail, err := json.Marshal(struct { + Type string `json:"type"` + KeyID string `json:"keyId"` + Key string `json:"key"` + AppID string `json:"appId"` + ClientID string `json:"clientID"` + }{ + Type: "application", + KeyID: key.KeyID, + Key: string(key.PrivateKey), + AppID: key.ApplicationID, + ClientID: key.ClientID, + }) + logging.Log("MANAG-adt42").OnError(err).Warn("unable to marshall key") + + return &management.AddClientKeyResponse{ + Id: key.KeyID, + CreationDate: creationDate, + ExpirationDate: expirationDate, + Sequence: key.Sequence, + KeyDetails: detail, + Type: authNKeyTypeFromModel(key.Type), + } +} + +func authNKeyTypeToModel(typ management.AuthNKeyType) key_model.AuthNKeyType { + switch typ { + case management.AuthNKeyType_AUTHNKEY_JSON: + return key_model.AuthNKeyTypeJSON + default: + return key_model.AuthNKeyTypeNONE + } +} + +func authNKeyTypeFromModel(typ key_model.AuthNKeyType) management.AuthNKeyType { + switch typ { + case key_model.AuthNKeyTypeJSON: + return management.AuthNKeyType_AUTHNKEY_JSON + default: + return management.AuthNKeyType_AUTHNKEY_UNSPECIFIED + } +} + +func clientKeySearchRequestToModel(req *management.ClientKeySearchRequest) *key_model.AuthNKeySearchRequest { + return &key_model.AuthNKeySearchRequest{ + Offset: req.Offset, + Limit: req.Limit, + Asc: req.Asc, + Queries: []*key_model.AuthNKeySearchQuery{ + { + Key: key_model.AuthNKeyObjectType, + Method: model.SearchMethodEquals, + Value: key_model.AuthNKeyObjectTypeApplication, + }, { + Key: key_model.AuthNKeyObjectID, + Method: model.SearchMethodEquals, + Value: req.ApplicationId, + }, + }, + } +} + +func clientKeySearchResponseFromModel(req *key_model.AuthNKeySearchResponse) *management.ClientKeySearchResponse { + viewTimestamp, err := ptypes.TimestampProto(req.Timestamp) + logging.Log("MANAG-Sk9ds").OnError(err).Debug("unable to parse cretaion date") + + return &management.ClientKeySearchResponse{ + Offset: req.Offset, + Limit: req.Limit, + TotalResult: req.TotalResult, + ProcessedSequence: req.Sequence, + ViewTimestamp: viewTimestamp, + Result: clientKeyViewsFromModel(req.Result...), + } +} diff --git a/internal/api/grpc/management/user_machine_converter.go b/internal/api/grpc/management/user_machine_converter.go index fd1d651d6..cfb19844c 100644 --- a/internal/api/grpc/management/user_machine_converter.go +++ b/internal/api/grpc/management/user_machine_converter.go @@ -12,6 +12,7 @@ import ( "github.com/golang/protobuf/ptypes" "github.com/caos/zitadel/internal/eventstore/models" + key_model "github.com/caos/zitadel/internal/key/model" "github.com/caos/zitadel/internal/model" usr_model "github.com/caos/zitadel/internal/user/model" "github.com/caos/zitadel/pkg/grpc/management" @@ -52,7 +53,7 @@ func machineViewFromModel(machine *usr_model.MachineView) *management.MachineVie } } -func machineKeyViewsFromModel(keys ...*usr_model.MachineKeyView) []*management.MachineKeyView { +func authnKeyViewsFromModel(keys ...*key_model.AuthNKeyView) []*management.MachineKeyView { keyViews := make([]*management.MachineKeyView, len(keys)) for i, key := range keys { keyViews[i] = machineKeyViewFromModel(key) @@ -60,7 +61,7 @@ func machineKeyViewsFromModel(keys ...*usr_model.MachineKeyView) []*management.M return keyViews } -func machineKeyViewFromModel(key *usr_model.MachineKeyView) *management.MachineKeyView { +func machineKeyViewFromModel(key *key_model.AuthNKeyView) *management.MachineKeyView { creationDate, err := ptypes.TimestampProto(key.CreationDate) logging.Log("MANAG-gluk7").OnError(err).Debug("unable to parse timestamp") @@ -133,23 +134,27 @@ func machineKeyTypeFromDomain(typ domain.MachineKeyType) management.MachineKeyTy } } -func machineKeyTypeFromModel(typ usr_model.MachineKeyType) management.MachineKeyType { +func machineKeyTypeFromModel(typ key_model.AuthNKeyType) management.MachineKeyType { switch typ { - case usr_model.MachineKeyTypeJSON: + case key_model.AuthNKeyTypeJSON: return management.MachineKeyType_MACHINEKEY_JSON default: return management.MachineKeyType_MACHINEKEY_UNSPECIFIED } } -func machineKeySearchRequestToModel(req *management.MachineKeySearchRequest) *usr_model.MachineKeySearchRequest { - return &usr_model.MachineKeySearchRequest{ +func machineKeySearchRequestToModel(req *management.MachineKeySearchRequest) *key_model.AuthNKeySearchRequest { + return &key_model.AuthNKeySearchRequest{ Offset: req.Offset, Limit: req.Limit, Asc: req.Asc, - Queries: []*usr_model.MachineKeySearchQuery{ + Queries: []*key_model.AuthNKeySearchQuery{ { - Key: usr_model.MachineKeyKeyUserID, + Key: key_model.AuthNKeyObjectType, + Method: model.SearchMethodEquals, + Value: key_model.AuthNKeyObjectTypeUser, + }, { + Key: key_model.AuthNKeyObjectID, Method: model.SearchMethodEquals, Value: req.UserId, }, @@ -157,7 +162,7 @@ func machineKeySearchRequestToModel(req *management.MachineKeySearchRequest) *us } } -func machineKeySearchResponseFromModel(req *usr_model.MachineKeySearchResponse) *management.MachineKeySearchResponse { +func machineKeySearchResponseFromModel(req *key_model.AuthNKeySearchResponse) *management.MachineKeySearchResponse { viewTimestamp, err := ptypes.TimestampProto(req.Timestamp) logging.Log("MANAG-Sk9ds").OnError(err).Debug("unable to parse cretaion date") @@ -167,6 +172,6 @@ func machineKeySearchResponseFromModel(req *usr_model.MachineKeySearchResponse) TotalResult: req.TotalResult, ProcessedSequence: req.Sequence, ViewTimestamp: viewTimestamp, - Result: machineKeyViewsFromModel(req.Result...), + Result: authnKeyViewsFromModel(req.Result...), } } diff --git a/internal/api/grpc/server/middleware/auth_interceptor_test.go b/internal/api/grpc/server/middleware/auth_interceptor_test.go index 671e64f3a..5f02048f8 100644 --- a/internal/api/grpc/server/middleware/auth_interceptor_test.go +++ b/internal/api/grpc/server/middleware/auth_interceptor_test.go @@ -24,9 +24,10 @@ type verifierMock struct{} func (v *verifierMock) VerifyAccessToken(ctx context.Context, token, clientID string) (string, string, string, string, error) { return "", "", "", "", nil } -func (v *verifierMock) ResolveGrants(ctx context.Context) (*authz.Grant, error) { +func (v *verifierMock) SearchMyMemberships(ctx context.Context) ([]*authz.Membership, error) { return nil, nil } + func (v *verifierMock) ProjectIDAndOriginsByClientID(ctx context.Context, clientID string) (string, []string, error) { return "", nil, nil } diff --git a/internal/api/oidc/client.go b/internal/api/oidc/client.go index 39fffdba0..8d7a653a9 100644 --- a/internal/api/oidc/client.go +++ b/internal/api/oidc/client.go @@ -12,6 +12,7 @@ import ( "github.com/caos/zitadel/internal/api/authz" "github.com/caos/zitadel/internal/api/http" "github.com/caos/zitadel/internal/auth_request/model" + authreq_model "github.com/caos/zitadel/internal/auth_request/model" "github.com/caos/zitadel/internal/crypto" "github.com/caos/zitadel/internal/errors" proj_model "github.com/caos/zitadel/internal/project/model" @@ -55,13 +56,17 @@ func (o *OPStorage) GetClientByClientID(ctx context.Context, id string) (_ op.Cl } func (o *OPStorage) GetKeyByIDAndUserID(ctx context.Context, keyID, userID string) (_ *jose.JSONWebKey, err error) { + return o.GetKeyByIDAndIssuer(ctx, keyID, userID) +} + +func (o *OPStorage) GetKeyByIDAndIssuer(ctx context.Context, keyID, issuer string) (_ *jose.JSONWebKey, err error) { ctx, span := tracing.NewSpan(ctx) defer func() { span.EndWithError(err) }() key, err := o.repo.MachineKeyByID(ctx, keyID) if err != nil { return nil, err } - if key.UserID != userID { + if key.AuthIdentifier != issuer { return nil, errors.ThrowPermissionDenied(nil, "OIDC-24jm3", "key from different user") } publicKey, err := crypto.BytesToPublicKey(key.PublicKey) @@ -75,6 +80,29 @@ func (o *OPStorage) GetKeyByIDAndUserID(ctx context.Context, keyID, userID strin }, nil } +func (o *OPStorage) ValidateJWTProfileScopes(ctx context.Context, subject string, scopes oidc.Scopes) (oidc.Scopes, error) { + user, err := o.repo.UserByID(ctx, subject) + if err != nil { + return nil, err + } + for i := len(scopes) - 1; i >= 0; i-- { + scope := scopes[i] + if strings.HasPrefix(scope, authreq_model.OrgDomainPrimaryScope) { + var orgID string + org, err := o.repo.OrgByPrimaryDomain(strings.TrimPrefix(scope, authreq_model.OrgDomainPrimaryScope)) + if err == nil { + orgID = org.ID + } + if orgID != user.ResourceOwner { + scopes[i] = scopes[len(scopes)-1] + scopes[len(scopes)-1] = "" + scopes = scopes[:len(scopes)-1] + } + } + } + return scopes, nil +} + func (o *OPStorage) AuthorizeClientIDSecret(ctx context.Context, id string, secret string) (err error) { ctx, span := tracing.NewSpan(ctx) defer func() { span.EndWithError(err) }() @@ -85,33 +113,32 @@ func (o *OPStorage) AuthorizeClientIDSecret(ctx context.Context, id string, secr return o.repo.AuthorizeOIDCApplication(ctx, id, secret) } -func (o *OPStorage) GetUserinfoFromToken(ctx context.Context, tokenID, subject, origin string) (_ oidc.UserInfo, err error) { +func (o *OPStorage) SetUserinfoFromToken(ctx context.Context, userInfo oidc.UserInfoSetter, tokenID, subject, origin string) (err error) { ctx, span := tracing.NewSpan(ctx) defer func() { span.EndWithError(err) }() token, err := o.repo.TokenByID(ctx, subject, tokenID) if err != nil { - return nil, errors.ThrowPermissionDenied(nil, "OIDC-Dsfb2", "token is not valid or has expired") + return errors.ThrowPermissionDenied(nil, "OIDC-Dsfb2", "token is not valid or has expired") } if token.ApplicationID != "" { app, err := o.repo.ApplicationByClientID(ctx, token.ApplicationID) if err != nil { - return nil, err + return err } if origin != "" && !http.IsOriginAllowed(app.OriginAllowList, origin) { - return nil, errors.ThrowPermissionDenied(nil, "OIDC-da1f3", "origin is not allowed") + return errors.ThrowPermissionDenied(nil, "OIDC-da1f3", "origin is not allowed") } } - return o.GetUserinfoFromScopes(ctx, token.UserID, token.ApplicationID, token.Scopes) + return o.SetUserinfoFromScopes(ctx, userInfo, token.UserID, token.ApplicationID, token.Scopes) } -func (o *OPStorage) GetUserinfoFromScopes(ctx context.Context, userID, applicationID string, scopes []string) (_ oidc.UserInfo, err error) { +func (o *OPStorage) SetUserinfoFromScopes(ctx context.Context, userInfo oidc.UserInfoSetter, userID, applicationID string, scopes []string) (err error) { ctx, span := tracing.NewSpan(ctx) defer func() { span.EndWithError(err) }() user, err := o.repo.UserByID(ctx, userID) if err != nil { - return nil, err + return err } - userInfo := oidc.NewUserInfo() roles := make([]string, 0) for _, scope := range scopes { switch scope { @@ -160,17 +187,40 @@ func (o *OPStorage) GetUserinfoFromScopes(ctx context.Context, userID, applicati } if len(roles) == 0 || applicationID == "" { - return userInfo, nil + return nil } projectRoles, err := o.assertRoles(ctx, userID, applicationID, roles) if err != nil { - return nil, err + return err } if len(projectRoles) > 0 { userInfo.AppendClaims(ClaimProjectRoles, projectRoles) } - return userInfo, nil + return nil +} + +func (o *OPStorage) SetIntrospectionFromToken(ctx context.Context, introspection oidc.IntrospectionResponse, tokenID, subject, clientID string) error { + token, err := o.repo.TokenByID(ctx, subject, tokenID) + if err != nil { + return errors.ThrowPermissionDenied(nil, "OIDC-Dsfb2", "token is not valid or has expired") + } + app, err := o.repo.ApplicationByClientID(ctx, clientID) + if err != nil { + return errors.ThrowPermissionDenied(nil, "OIDC-Adfg5", "client not found") + } + for _, aud := range token.Audience { + if aud == clientID || aud == app.ProjectID { + err := o.SetUserinfoFromScopes(ctx, introspection, token.UserID, clientID, token.Scopes) + if err != nil { + return err + } + introspection.SetScopes(token.Scopes) + introspection.SetClientID(token.ApplicationID) + return nil + } + } + return errors.ThrowPermissionDenied(nil, "OIDC-sdg3G", "token is not valid for this client") } func (o *OPStorage) GetPrivateClaimsFromScopes(ctx context.Context, userID, clientID string, scopes []string) (claims map[string]interface{}, err error) { diff --git a/internal/api/oidc/client_converter.go b/internal/api/oidc/client_converter.go index a1d915382..6098dd43c 100644 --- a/internal/api/oidc/client_converter.go +++ b/internal/api/oidc/client_converter.go @@ -1,13 +1,13 @@ package oidc import ( - authreq_model "github.com/caos/zitadel/internal/auth_request/model" "strings" "time" "github.com/caos/oidc/pkg/oidc" "github.com/caos/oidc/pkg/op" + authreq_model "github.com/caos/zitadel/internal/auth_request/model" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/project/model" ) @@ -37,7 +37,7 @@ func (c *Client) ApplicationType() op.ApplicationType { return op.ApplicationType(c.OIDCApplicationType) } -func (c *Client) AuthMethod() op.AuthMethod { +func (c *Client) AuthMethod() oidc.AuthMethod { return authMethodToOIDC(c.OIDCAuthMethodType) } @@ -129,16 +129,18 @@ func accessTokenTypeToOIDC(tokenType model.OIDCTokenType) op.AccessTokenType { } } -func authMethodToOIDC(authType model.OIDCAuthMethodType) op.AuthMethod { +func authMethodToOIDC(authType model.OIDCAuthMethodType) oidc.AuthMethod { switch authType { case model.OIDCAuthMethodTypeBasic: - return op.AuthMethodBasic + return oidc.AuthMethodBasic case model.OIDCAuthMethodTypePost: - return op.AuthMethodPost + return oidc.AuthMethodPost case model.OIDCAuthMethodTypeNone: - return op.AuthMethodNone + return oidc.AuthMethodNone + case model.OIDCAuthMethodTypePrivateKeyJWT: + return oidc.AuthMethodPrivateKeyJWT default: - return op.AuthMethodBasic + return oidc.AuthMethodBasic } } diff --git a/internal/api/oidc/op.go b/internal/api/oidc/op.go index de1ffa4f0..1de8f8a20 100644 --- a/internal/api/oidc/op.go +++ b/internal/api/oidc/op.go @@ -2,9 +2,6 @@ package oidc import ( "context" - "github.com/caos/zitadel/internal/telemetry/metrics" - "github.com/caos/zitadel/internal/v2/command" - "github.com/caos/zitadel/internal/v2/query" "time" "github.com/caos/logging" @@ -15,7 +12,10 @@ import ( "github.com/caos/zitadel/internal/auth/repository" "github.com/caos/zitadel/internal/config/types" "github.com/caos/zitadel/internal/id" + "github.com/caos/zitadel/internal/telemetry/metrics" "github.com/caos/zitadel/internal/telemetry/tracing" + "github.com/caos/zitadel/internal/v2/command" + "github.com/caos/zitadel/internal/v2/query" ) type OPHandlerConfig struct { @@ -34,11 +34,12 @@ type StorageConfig struct { } type EndpointConfig struct { - Auth *Endpoint - Token *Endpoint - Userinfo *Endpoint - EndSession *Endpoint - Keys *Endpoint + Auth *Endpoint + Token *Endpoint + Introspection *Endpoint + Userinfo *Endpoint + EndSession *Endpoint + Keys *Endpoint } type Endpoint struct { @@ -74,6 +75,7 @@ func NewProvider(ctx context.Context, config OPHandlerConfig, command *command.C ), op.WithCustomAuthEndpoint(op.NewEndpointWithURL(config.Endpoints.Auth.Path, config.Endpoints.Auth.URL)), op.WithCustomTokenEndpoint(op.NewEndpointWithURL(config.Endpoints.Token.Path, config.Endpoints.Token.URL)), + op.WithCustomIntrospectionEndpoint(op.NewEndpointWithURL(config.Endpoints.Introspection.Path, config.Endpoints.Introspection.URL)), op.WithCustomUserinfoEndpoint(op.NewEndpointWithURL(config.Endpoints.Userinfo.Path, config.Endpoints.Userinfo.URL)), op.WithCustomEndSessionEndpoint(op.NewEndpointWithURL(config.Endpoints.EndSession.Path, config.Endpoints.EndSession.URL)), op.WithCustomKeysEndpoint(op.NewEndpointWithURL(config.Endpoints.Keys.Path, config.Endpoints.Keys.URL)), diff --git a/internal/auth/repository/eventsourcing/eventstore/org.go b/internal/auth/repository/eventsourcing/eventstore/org.go index 062410e58..83313647b 100644 --- a/internal/auth/repository/eventsourcing/eventstore/org.go +++ b/internal/auth/repository/eventsourcing/eventstore/org.go @@ -4,6 +4,7 @@ import ( "context" "github.com/caos/logging" + "github.com/caos/zitadel/internal/api/authz" "github.com/caos/zitadel/internal/config/systemdefaults" "github.com/caos/zitadel/internal/errors" @@ -52,6 +53,14 @@ func (repo *OrgRepository) SearchOrgs(ctx context.Context, request *org_model.Or return result, nil } +func (repo *OrgRepository) OrgByPrimaryDomain(primaryDomain string) (*org_model.OrgView, error) { + org, err := repo.View.OrgByPrimaryDomain(primaryDomain) + if err != nil { + return nil, err + } + return model.OrgToModel(org), nil +} + func (repo *OrgRepository) GetDefaultOrgIAMPolicy(ctx context.Context) (*iam_model.OrgIAMPolicyView, error) { orgPolicy, err := repo.View.OrgIAMPolicyByAggregateID(repo.SystemDefaults.IamID) if err != nil { diff --git a/internal/auth/repository/eventsourcing/eventstore/token.go b/internal/auth/repository/eventsourcing/eventstore/token.go index d71523c98..47b040b3e 100644 --- a/internal/auth/repository/eventsourcing/eventstore/token.go +++ b/internal/auth/repository/eventsourcing/eventstore/token.go @@ -2,20 +2,23 @@ package eventstore import ( "context" + "time" + "github.com/caos/logging" + + "github.com/caos/zitadel/internal/auth/repository/eventsourcing/view" "github.com/caos/zitadel/internal/errors" + proj_event "github.com/caos/zitadel/internal/project/repository/eventsourcing" "github.com/caos/zitadel/internal/telemetry/tracing" usr_model "github.com/caos/zitadel/internal/user/model" user_event "github.com/caos/zitadel/internal/user/repository/eventsourcing" "github.com/caos/zitadel/internal/user/repository/view/model" - "time" - - "github.com/caos/zitadel/internal/auth/repository/eventsourcing/view" ) type TokenRepo struct { - UserEvents *user_event.UserEventstore - View *view.View + UserEvents *user_event.UserEventstore + ProjectEvents *proj_event.ProjectEventstore + View *view.View } func (repo *TokenRepo) IsTokenValid(ctx context.Context, userID, tokenID string) (bool, error) { diff --git a/internal/auth/repository/eventsourcing/eventstore/user.go b/internal/auth/repository/eventsourcing/eventstore/user.go index 66248090f..dbb0bf903 100644 --- a/internal/auth/repository/eventsourcing/eventstore/user.go +++ b/internal/auth/repository/eventsourcing/eventstore/user.go @@ -5,6 +5,7 @@ import ( "github.com/caos/zitadel/internal/config/systemdefaults" iam_es_model "github.com/caos/zitadel/internal/iam/repository/view/model" + key_model "github.com/caos/zitadel/internal/key/model" "github.com/caos/logging" @@ -14,6 +15,7 @@ import ( "github.com/caos/zitadel/internal/eventstore" es_models "github.com/caos/zitadel/internal/eventstore/models" "github.com/caos/zitadel/internal/eventstore/sdk" + key_view_model "github.com/caos/zitadel/internal/key/repository/view/model" org_model "github.com/caos/zitadel/internal/org/model" org_event "github.com/caos/zitadel/internal/org/repository/eventsourcing" "github.com/caos/zitadel/internal/telemetry/tracing" @@ -252,10 +254,10 @@ func checkIDs(ctx context.Context, obj es_models.ObjectRoot) error { return nil } -func (repo *UserRepo) MachineKeyByID(ctx context.Context, keyID string) (*model.MachineKeyView, error) { - key, err := repo.View.MachineKeyByID(keyID) +func (repo *UserRepo) MachineKeyByID(ctx context.Context, keyID string) (*key_model.AuthNKeyView, error) { + key, err := repo.View.AuthNKeyByID(keyID) if err != nil { return nil, err } - return usr_view_model.MachineKeyToModel(key), nil + return key_view_model.AuthNKeyToModel(key), nil } diff --git a/internal/auth/repository/eventsourcing/eventstore/user_grant.go b/internal/auth/repository/eventsourcing/eventstore/user_grant.go index cba39e431..e2bbd6370 100644 --- a/internal/auth/repository/eventsourcing/eventstore/user_grant.go +++ b/internal/auth/repository/eventsourcing/eventstore/user_grant.go @@ -2,7 +2,6 @@ package eventstore import ( "context" - "github.com/caos/logging" "github.com/caos/zitadel/internal/api/authz" @@ -39,7 +38,7 @@ func (repo *UserGrantRepo) SearchMyUserGrants(ctx context.Context, request *gran result := &grant_model.UserGrantSearchResponse{ Offset: request.Offset, Limit: request.Limit, - TotalResult: uint64(count), + TotalResult: count, Result: model.UserGrantsToModel(grants), } if err == nil { @@ -94,7 +93,43 @@ func membershipsToOrgResp(memberships []*user_view_model.UserMembershipView, cou } } +func (repo *UserGrantRepo) SearchMyUserMemberships(ctx context.Context, request *user_model.UserMembershipSearchRequest) (*user_model.UserMembershipSearchResponse, error) { + request.EnsureLimit(repo.SearchLimit) + sequence, sequenceErr := repo.View.GetLatestUserMembershipSequence() + logging.Log("EVENT-Dn7sf").OnError(sequenceErr).Warn("could not read latest user sequence") + + memberships, count, err := repo.View.SearchUserMemberships(request) + if err != nil { + return nil, err + } + result := &user_model.UserMembershipSearchResponse{ + Offset: request.Offset, + Limit: request.Limit, + TotalResult: count, + Result: user_view_model.UserMembershipsToModel(memberships), + } + if sequenceErr == nil { + result.Sequence = sequence.CurrentSequence + result.Timestamp = sequence.LastSuccessfulSpoolerRun + } + return result, nil +} + func (repo *UserGrantRepo) SearchMyZitadelPermissions(ctx context.Context) ([]string, error) { + memberships, err := repo.searchUserMemberships(ctx) + if err != nil { + return nil, err + } + permissions := &grant_model.Permissions{Permissions: []string{}} + for _, membership := range memberships { + for _, role := range membership.Roles { + permissions = repo.mapRoleToPermission(permissions, membership, role) + } + } + return permissions.Permissions, nil +} + +func (repo *UserGrantRepo) searchUserMemberships(ctx context.Context) ([]*user_view_model.UserMembershipView, error) { ctxData := authz.GetCtxData(ctx) orgMemberships, orgCount, err := repo.View.SearchUserMemberships(&user_model.UserMembershipSearchRequest{ Queries: []*user_model.UserMembershipSearchQuery{ @@ -131,16 +166,9 @@ func (repo *UserGrantRepo) SearchMyZitadelPermissions(ctx context.Context) ([]st return nil, err } if orgCount == 0 && iamCount == 0 { - return []string{}, nil + return []*user_view_model.UserMembershipView{}, nil } - orgMemberships = append(orgMemberships, iamMemberships...) - permissions := &grant_model.Permissions{Permissions: []string{}} - for _, membership := range orgMemberships { - for _, role := range membership.Roles { - permissions = repo.mapRoleToPermission(permissions, membership, role) - } - } - return permissions.Permissions, nil + return append(orgMemberships, iamMemberships...), nil } func (repo *UserGrantRepo) SearchMyProjectPermissions(ctx context.Context) ([]string, error) { @@ -258,7 +286,7 @@ func grantRespToOrgResp(grants *grant_model.UserGrantSearchResponse) *grant_mode func orgRespToOrgResp(orgs []*org_view_model.OrgView, count uint64) *grant_model.ProjectOrgSearchResponse { resp := &grant_model.ProjectOrgSearchResponse{ - TotalResult: uint64(count), + TotalResult: count, } resp.Result = make([]*grant_model.Org, len(orgs)) for i, o := range orgs { @@ -267,33 +295,6 @@ func orgRespToOrgResp(orgs []*org_view_model.OrgView, count uint64) *grant_model return resp } -func mergeOrgAndAdminGrant(ctxData authz.CtxData, orgGrant, iamAdminGrant *model.UserGrantView) (grant *authz.Grant) { - if orgGrant != nil { - roles := orgGrant.RoleKeys - if iamAdminGrant != nil { - roles = addIamAdminRoles(roles, iamAdminGrant.RoleKeys) - } - grant = &authz.Grant{OrgID: orgGrant.ResourceOwner, Roles: roles} - } else if iamAdminGrant != nil { - grant = &authz.Grant{ - OrgID: ctxData.OrgID, - Roles: iamAdminGrant.RoleKeys, - } - } - return grant -} - -func addIamAdminRoles(orgRoles, iamAdminRoles []string) []string { - result := make([]string, 0) - result = append(result, iamAdminRoles...) - for _, role := range orgRoles { - if !authz.ExistsPerm(result, role) { - result = append(result, role) - } - } - return result -} - func containsOrg(orgs []*grant_model.Org, resourceOwner string) bool { for _, org := range orgs { if org.OrgID == resourceOwner { @@ -302,3 +303,20 @@ func containsOrg(orgs []*grant_model.Org, resourceOwner string) bool { } return false } + +func userMembershipToMembership(membership *user_view_model.UserMembershipView) *authz.Membership { + return &authz.Membership{ + MemberType: authz.MemberType(membership.MemberType), + AggregateID: membership.AggregateID, + ObjectID: membership.ObjectID, + Roles: membership.Roles, + } +} + +func userMembershipsToMemberships(memberships []*user_view_model.UserMembershipView) []*authz.Membership { + result := make([]*authz.Membership, len(memberships)) + for i, m := range memberships { + result[i] = userMembershipToMembership(m) + } + return result +} diff --git a/internal/auth/repository/eventsourcing/handler/application.go b/internal/auth/repository/eventsourcing/handler/application.go index f8bd45d33..49fa80282 100644 --- a/internal/auth/repository/eventsourcing/handler/application.go +++ b/internal/auth/repository/eventsourcing/handler/application.go @@ -84,6 +84,8 @@ func (a *Application) Reduce(event *models.Event) (err error) { case es_model.ApplicationChanged, es_model.OIDCConfigAdded, es_model.OIDCConfigChanged, + es_model.APIConfigAdded, + es_model.APIConfigChanged, es_model.ApplicationDeactivated, es_model.ApplicationReactivated: err = app.SetData(event) diff --git a/internal/auth/repository/eventsourcing/handler/authn_keys.go b/internal/auth/repository/eventsourcing/handler/authn_keys.go new file mode 100644 index 000000000..0300b6b1b --- /dev/null +++ b/internal/auth/repository/eventsourcing/handler/authn_keys.go @@ -0,0 +1,120 @@ +package handler + +import ( + "time" + + "github.com/caos/logging" + + "github.com/caos/zitadel/internal/eventstore" + es_models "github.com/caos/zitadel/internal/eventstore/models" + "github.com/caos/zitadel/internal/eventstore/query" + "github.com/caos/zitadel/internal/eventstore/spooler" + key_model "github.com/caos/zitadel/internal/key/repository/view/model" + proj_model "github.com/caos/zitadel/internal/project/repository/eventsourcing/model" + user_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model" +) + +const ( + authnKeysTable = "auth.authn_keys" +) + +type AuthNKeys struct { + handler + subscription *eventstore.Subscription +} + +func newAuthNKeys(handler handler) *AuthNKeys { + h := &AuthNKeys{ + handler: handler, + } + + h.subscribe() + + return h +} + +func (k *AuthNKeys) subscribe() { + k.subscription = k.es.Subscribe(k.AggregateTypes()...) + go func() { + for event := range k.subscription.Events { + query.ReduceEvent(k, event) + } + }() +} + +func (k *AuthNKeys) ViewModel() string { + return authnKeysTable +} + +func (_ *AuthNKeys) AggregateTypes() []es_models.AggregateType { + return []es_models.AggregateType{user_model.UserAggregate, proj_model.ProjectAggregate} +} + +func (k *AuthNKeys) CurrentSequence() (uint64, error) { + sequence, err := k.view.GetLatestAuthNKeySequence() + if err != nil { + return 0, err + } + return sequence.CurrentSequence, nil +} + +func (k *AuthNKeys) EventQuery() (*es_models.SearchQuery, error) { + sequence, err := k.view.GetLatestAuthNKeySequence() + if err != nil { + return nil, err + } + return es_models.NewSearchQuery(). + AggregateTypeFilter(k.AggregateTypes()...). + LatestSequenceFilter(sequence.CurrentSequence), nil +} + +func (k *AuthNKeys) Reduce(event *es_models.Event) (err error) { + switch event.AggregateType { + case user_model.UserAggregate, + proj_model.ProjectAggregate: + err = k.processAuthNKeys(event) + } + return err +} + +func (k *AuthNKeys) processAuthNKeys(event *es_models.Event) (err error) { + key := new(key_model.AuthNKeyView) + switch event.Type { + case user_model.MachineKeyAdded, + proj_model.ClientKeyAdded: + err = key.AppendEvent(event) + if key.ExpirationDate.Before(time.Now()) { + return k.view.ProcessedAuthNKeySequence(event) + } + case user_model.MachineKeyRemoved: + err = key.SetUserData(event) + if err != nil { + return err + } + return k.view.DeleteAuthNKey(key.ID, event) + case proj_model.ClientKeyRemoved: + err = key.SetClientData(event) + if err != nil { + return err + } + return k.view.DeleteAuthNKey(key.ID, event) + case user_model.UserRemoved, + proj_model.ApplicationRemoved: + return k.view.DeleteAuthNKeysByObjectID(event.AggregateID, event) + default: + return k.view.ProcessedAuthNKeySequence(event) + } + if err != nil { + return err + } + return k.view.PutAuthNKey(key, event) +} + +func (k *AuthNKeys) OnError(event *es_models.Event, err error) error { + logging.LogWithFields("SPOOL-S9fe", "id", event.AggregateID).WithError(err).Warn("something went wrong in authn key handler") + return spooler.HandleError(event, err, k.view.GetLatestAuthNKeyFailedEvent, k.view.ProcessedAuthNKeyFailedEvent, k.view.ProcessedAuthNKeySequence, k.errorCountUntilSkip) +} + +func (k *AuthNKeys) OnSuccess() error { + return spooler.HandleSuccess(k.view.UpdateAuthNKeySpoolerRunTimestamp) +} diff --git a/internal/auth/repository/eventsourcing/handler/handler.go b/internal/auth/repository/eventsourcing/handler/handler.go index c5825c5ab..b22983587 100644 --- a/internal/auth/repository/eventsourcing/handler/handler.go +++ b/internal/auth/repository/eventsourcing/handler/handler.go @@ -71,7 +71,7 @@ func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, es repos.OrgEvents, repos.IamEvents, systemDefaults.IamID), - newMachineKeys( + newAuthNKeys( handler{view, bulkLimit, configs.cycleDuration("MachineKey"), errorCount, es}), newLoginPolicy( handler{view, bulkLimit, configs.cycleDuration("LoginPolicy"), errorCount, es}), diff --git a/internal/auth/repository/eventsourcing/handler/machine_keys.go b/internal/auth/repository/eventsourcing/handler/machine_keys.go deleted file mode 100644 index bf877564a..000000000 --- a/internal/auth/repository/eventsourcing/handler/machine_keys.go +++ /dev/null @@ -1,110 +0,0 @@ -package handler - -import ( - "time" - - "github.com/caos/logging" - - "github.com/caos/zitadel/internal/eventstore" - es_models "github.com/caos/zitadel/internal/eventstore/models" - "github.com/caos/zitadel/internal/eventstore/query" - "github.com/caos/zitadel/internal/eventstore/spooler" - "github.com/caos/zitadel/internal/user/repository/eventsourcing/model" - usr_model "github.com/caos/zitadel/internal/user/repository/view/model" -) - -const ( - machineKeysTable = "auth.machine_keys" -) - -type MachineKeys struct { - handler - subscription *eventstore.Subscription -} - -func newMachineKeys(handler handler) *MachineKeys { - h := &MachineKeys{ - handler: handler, - } - - h.subscribe() - - return h -} - -func (k *MachineKeys) subscribe() { - k.subscription = k.es.Subscribe(k.AggregateTypes()...) - go func() { - for event := range k.subscription.Events { - query.ReduceEvent(k, event) - } - }() -} - -func (k *MachineKeys) ViewModel() string { - return machineKeysTable -} - -func (_ *MachineKeys) AggregateTypes() []es_models.AggregateType { - return []es_models.AggregateType{model.UserAggregate} -} - -func (k *MachineKeys) CurrentSequence() (uint64, error) { - sequence, err := k.view.GetLatestMachineKeySequence() - if err != nil { - return 0, err - } - return sequence.CurrentSequence, nil -} - -func (k *MachineKeys) EventQuery() (*es_models.SearchQuery, error) { - sequence, err := k.view.GetLatestMachineKeySequence() - if err != nil { - return nil, err - } - return es_models.NewSearchQuery(). - AggregateTypeFilter(k.AggregateTypes()...). - LatestSequenceFilter(sequence.CurrentSequence), nil -} - -func (k *MachineKeys) Reduce(event *es_models.Event) (err error) { - switch event.AggregateType { - case model.UserAggregate: - err = k.processMachineKeys(event) - } - return err -} - -func (k *MachineKeys) processMachineKeys(event *es_models.Event) (err error) { - key := new(usr_model.MachineKeyView) - switch event.Type { - case model.MachineKeyAdded: - err = key.AppendEvent(event) - if key.ExpirationDate.Before(time.Now()) { - return k.view.ProcessedMachineKeySequence(event) - } - case model.MachineKeyRemoved: - err = key.SetData(event) - if err != nil { - return err - } - return k.view.DeleteMachineKey(key.ID, event) - case model.UserRemoved: - return k.view.DeleteMachineKeysByUserID(event.AggregateID, event) - default: - return k.view.ProcessedMachineKeySequence(event) - } - if err != nil { - return err - } - return k.view.PutMachineKey(key, event) -} - -func (k *MachineKeys) OnError(event *es_models.Event, err error) error { - logging.LogWithFields("SPOOL-S9fe", "id", event.AggregateID).WithError(err).Warn("something went wrong in machine key handler") - return spooler.HandleError(event, err, k.view.GetLatestMachineKeyFailedEvent, k.view.ProcessedMachineKeyFailedEvent, k.view.ProcessedMachineKeySequence, k.errorCountUntilSkip) -} - -func (k *MachineKeys) OnSuccess() error { - return spooler.HandleSuccess(k.view.UpdateMachineKeySpoolerRunTimestamp) -} diff --git a/internal/auth/repository/eventsourcing/handler/token.go b/internal/auth/repository/eventsourcing/handler/token.go index 6a365580a..1b28d5fd1 100644 --- a/internal/auth/repository/eventsourcing/handler/token.go +++ b/internal/auth/repository/eventsourcing/handler/token.go @@ -5,6 +5,7 @@ import ( "encoding/json" "github.com/caos/logging" + caos_errs "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore" "github.com/caos/zitadel/internal/eventstore/models" @@ -71,9 +72,6 @@ func (t *Token) EventQuery() (*models.SearchQuery, error) { if err != nil { return nil, err } - if err != nil { - return nil, err - } return es_models.NewSearchQuery(). AggregateTypeFilter(user_es_model.UserAggregate, project_es_model.ProjectAggregate). LatestSequenceFilter(sequence.CurrentSequence), nil diff --git a/internal/auth/repository/eventsourcing/repository.go b/internal/auth/repository/eventsourcing/repository.go index c8622e24c..48b8a4696 100644 --- a/internal/auth/repository/eventsourcing/repository.go +++ b/internal/auth/repository/eventsourcing/repository.go @@ -2,6 +2,7 @@ package eventsourcing import ( "context" + "github.com/caos/zitadel/internal/api/authz" "github.com/caos/zitadel/internal/auth/repository/eventsourcing/eventstore" "github.com/caos/zitadel/internal/auth/repository/eventsourcing/handler" @@ -148,8 +149,9 @@ func Start(conf Config, authZ authz.Config, systemDefaults sd.SystemDefaults, co IAMID: systemDefaults.IamID, }, eventstore.TokenRepo{ - UserEvents: user, - View: view, + UserEvents: user, + ProjectEvents: project, + View: view, }, eventstore.KeyRepository{ View: view, diff --git a/internal/auth/repository/eventsourcing/view/authn_keys.go b/internal/auth/repository/eventsourcing/view/authn_keys.go new file mode 100644 index 000000000..4873c6478 --- /dev/null +++ b/internal/auth/repository/eventsourcing/view/authn_keys.go @@ -0,0 +1,74 @@ +package view + +import ( + "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/eventstore/models" + key_model "github.com/caos/zitadel/internal/key/model" + "github.com/caos/zitadel/internal/key/repository/view" + "github.com/caos/zitadel/internal/key/repository/view/model" + "github.com/caos/zitadel/internal/view/repository" +) + +const ( + authNKeyTable = "auth.authn_keys" +) + +func (v *View) AuthNKeyByIDs(userID, keyID string) (*model.AuthNKeyView, error) { + return view.AuthNKeyByIDs(v.Db, authNKeyTable, userID, keyID) +} + +func (v *View) AuthNKeysByObjectID(objectID string) ([]*model.AuthNKeyView, error) { + return view.AuthNKeysByObjectID(v.Db, authNKeyTable, objectID) +} + +func (v *View) AuthNKeyByID(keyID string) (*model.AuthNKeyView, error) { + return view.AuthNKeyByID(v.Db, authNKeyTable, keyID) +} + +func (v *View) SearchAuthNKeys(request *key_model.AuthNKeySearchRequest) ([]*model.AuthNKeyView, uint64, error) { + return view.SearchAuthNKeys(v.Db, authNKeyTable, request) +} + +func (v *View) PutAuthNKey(key *model.AuthNKeyView, event *models.Event) error { + err := view.PutAuthNKey(v.Db, authNKeyTable, key) + if err != nil { + return err + } + return v.ProcessedAuthNKeySequence(event) +} + +func (v *View) DeleteAuthNKey(keyID string, event *models.Event) error { + err := view.DeleteAuthNKey(v.Db, authNKeyTable, keyID) + if err != nil && !errors.IsNotFound(err) { + return err + } + return v.ProcessedAuthNKeySequence(event) +} + +func (v *View) DeleteAuthNKeysByObjectID(objectID string, event *models.Event) error { + err := view.DeleteAuthNKey(v.Db, authNKeyTable, objectID) + if err != nil && !errors.IsNotFound(err) { + return err + } + return v.ProcessedAuthNKeySequence(event) +} + +func (v *View) GetLatestAuthNKeySequence() (*repository.CurrentSequence, error) { + return v.latestSequence(authNKeyTable) +} + +func (v *View) ProcessedAuthNKeySequence(event *models.Event) error { + return v.saveCurrentSequence(authNKeyTable, event) +} + +func (v *View) UpdateAuthNKeySpoolerRunTimestamp() error { + return v.updateSpoolerRunSequence(authNKeyTable) +} + +func (v *View) GetLatestAuthNKeyFailedEvent(sequence uint64) (*repository.FailedEvent, error) { + return v.latestFailedEvent(authNKeyTable, sequence) +} + +func (v *View) ProcessedAuthNKeyFailedEvent(failedEvent *repository.FailedEvent) error { + return v.saveFailedEvent(failedEvent) +} diff --git a/internal/auth/repository/eventsourcing/view/machine_keys.go b/internal/auth/repository/eventsourcing/view/machine_keys.go deleted file mode 100644 index 908dc54d8..000000000 --- a/internal/auth/repository/eventsourcing/view/machine_keys.go +++ /dev/null @@ -1,74 +0,0 @@ -package view - -import ( - "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/models" - usr_model "github.com/caos/zitadel/internal/user/model" - "github.com/caos/zitadel/internal/user/repository/view" - "github.com/caos/zitadel/internal/user/repository/view/model" - "github.com/caos/zitadel/internal/view/repository" -) - -const ( - machineKeyTable = "auth.machine_keys" -) - -func (v *View) MachineKeyByIDs(userID, keyID string) (*model.MachineKeyView, error) { - return view.MachineKeyByIDs(v.Db, machineKeyTable, userID, keyID) -} - -func (v *View) MachineKeysByUserID(userID string) ([]*model.MachineKeyView, error) { - return view.MachineKeysByUserID(v.Db, machineKeyTable, userID) -} - -func (v *View) MachineKeyByID(keyID string) (*model.MachineKeyView, error) { - return view.MachineKeyByID(v.Db, machineKeyTable, keyID) -} - -func (v *View) SearchMachineKeys(request *usr_model.MachineKeySearchRequest) ([]*model.MachineKeyView, uint64, error) { - return view.SearchMachineKeys(v.Db, machineKeyTable, request) -} - -func (v *View) PutMachineKey(key *model.MachineKeyView, event *models.Event) error { - err := view.PutMachineKey(v.Db, machineKeyTable, key) - if err != nil { - return err - } - return v.ProcessedMachineKeySequence(event) -} - -func (v *View) DeleteMachineKey(keyID string, event *models.Event) error { - err := view.DeleteMachineKey(v.Db, machineKeyTable, keyID) - if err != nil && !errors.IsNotFound(err) { - return err - } - return v.ProcessedMachineKeySequence(event) -} - -func (v *View) DeleteMachineKeysByUserID(userID string, event *models.Event) error { - err := view.DeleteMachineKey(v.Db, machineKeyTable, userID) - if err != nil && !errors.IsNotFound(err) { - return err - } - return v.ProcessedMachineKeySequence(event) -} - -func (v *View) GetLatestMachineKeySequence() (*repository.CurrentSequence, error) { - return v.latestSequence(machineKeyTable) -} - -func (v *View) ProcessedMachineKeySequence(event *models.Event) error { - return v.saveCurrentSequence(machineKeyTable, event) -} - -func (v *View) UpdateMachineKeySpoolerRunTimestamp() error { - return v.updateSpoolerRunSequence(machineKeyTable) -} - -func (v *View) GetLatestMachineKeyFailedEvent(sequence uint64) (*repository.FailedEvent, error) { - return v.latestFailedEvent(machineKeyTable, sequence) -} - -func (v *View) ProcessedMachineKeyFailedEvent(failedEvent *repository.FailedEvent) error { - return v.saveFailedEvent(failedEvent) -} diff --git a/internal/auth/repository/org.go b/internal/auth/repository/org.go index cb38bcf87..878d4756a 100644 --- a/internal/auth/repository/org.go +++ b/internal/auth/repository/org.go @@ -3,9 +3,11 @@ package repository import ( "context" iam_model "github.com/caos/zitadel/internal/iam/model" + org_model "github.com/caos/zitadel/internal/org/model" ) type OrgRepository interface { + OrgByPrimaryDomain(primaryDomain string) (*org_model.OrgView, error) GetOrgIAMPolicy(ctx context.Context, orgID string) (*iam_model.OrgIAMPolicyView, error) GetDefaultOrgIAMPolicy(ctx context.Context) (*iam_model.OrgIAMPolicyView, error) GetIDPConfigByID(ctx context.Context, idpConfigID string) (*iam_model.IDPConfigView, error) diff --git a/internal/auth/repository/user.go b/internal/auth/repository/user.go index 46a93c13f..90bad714e 100644 --- a/internal/auth/repository/user.go +++ b/internal/auth/repository/user.go @@ -3,6 +3,8 @@ package repository import ( "context" + key_model "github.com/caos/zitadel/internal/key/model" + "github.com/caos/zitadel/internal/user/model" ) @@ -16,7 +18,7 @@ type UserRepository interface { UserByID(ctx context.Context, userID string) (*model.UserView, error) UserByLoginName(ctx context.Context, loginName string) (*model.UserView, error) - MachineKeyByID(ctx context.Context, keyID string) (*model.MachineKeyView, error) + MachineKeyByID(ctx context.Context, keyID string) (*key_model.AuthNKeyView, error) } type myUserRepo interface { @@ -37,4 +39,6 @@ type myUserRepo interface { GetMyPasswordless(ctx context.Context) ([]*model.WebAuthNToken, error) MyUserChanges(ctx context.Context, lastSequence uint64, limit uint64, sortAscending bool) (*model.UserChanges, error) + + SearchMyUserMemberships(ctx context.Context, request *model.UserMembershipSearchRequest) (*model.UserMembershipSearchResponse, error) } diff --git a/internal/authz/repository/eventsourcing/eventstore/user_grant.go b/internal/authz/repository/eventsourcing/eventstore/user_grant.go index 6028f3e49..28370187a 100644 --- a/internal/authz/repository/eventsourcing/eventstore/user_grant.go +++ b/internal/authz/repository/eventsourcing/eventstore/user_grant.go @@ -7,8 +7,10 @@ import ( "github.com/caos/zitadel/internal/authz/repository/eventsourcing/view" caos_errs "github.com/caos/zitadel/internal/errors" iam_event "github.com/caos/zitadel/internal/iam/repository/eventsourcing" + global_model "github.com/caos/zitadel/internal/model" + user_model "github.com/caos/zitadel/internal/user/model" + user_view_model "github.com/caos/zitadel/internal/user/repository/view/model" grant_model "github.com/caos/zitadel/internal/usergrant/model" - "github.com/caos/zitadel/internal/usergrant/repository/view/model" "github.com/caos/zitadel/internal/v2/domain" ) @@ -24,46 +26,70 @@ func (repo *UserGrantRepo) Health() error { return repo.View.Health() } -func (repo *UserGrantRepo) ResolveGrants(ctx context.Context) (*authz.Grant, error) { - err := repo.FillIamProjectID(ctx) +func (repo *UserGrantRepo) SearchMyMemberships(ctx context.Context) ([]*authz.Membership, error) { + memberships, err := repo.searchUserMemberships(ctx) if err != nil { return nil, err } - ctxData := authz.GetCtxData(ctx) - - orgGrant, err := repo.View.UserGrantByIDs(ctxData.OrgID, repo.IamProjectID, ctxData.UserID) - if err != nil && !caos_errs.IsNotFound(err) { - return nil, err - } - iamAdminGrant, err := repo.View.UserGrantByIDs(repo.IamID, repo.IamProjectID, ctxData.UserID) - if err != nil && !caos_errs.IsNotFound(err) { - return nil, err - } - - return mergeOrgAndAdminGrant(ctxData, orgGrant, iamAdminGrant), nil + return userMembershipsToMemberships(memberships), nil } func (repo *UserGrantRepo) SearchMyZitadelPermissions(ctx context.Context) ([]string, error) { - grant, err := repo.ResolveGrants(ctx) + memberships, err := repo.searchUserMemberships(ctx) if err != nil { return nil, err } - - if grant == nil { - return []string{}, nil - } permissions := &grant_model.Permissions{Permissions: []string{}} - for _, role := range grant.Roles { - roleName, ctxID := authz.SplitPermission(role) - for _, mapping := range repo.Auth.RolePermissionMappings { - if mapping.Role == roleName { - permissions.AppendPermissions(ctxID, mapping.Permissions...) - } + for _, membership := range memberships { + for _, role := range membership.Roles { + permissions = repo.mapRoleToPermission(permissions, membership, role) } } return permissions.Permissions, nil } +func (repo *UserGrantRepo) searchUserMemberships(ctx context.Context) ([]*user_view_model.UserMembershipView, error) { + ctxData := authz.GetCtxData(ctx) + orgMemberships, orgCount, err := repo.View.SearchUserMemberships(&user_model.UserMembershipSearchRequest{ + Queries: []*user_model.UserMembershipSearchQuery{ + { + Key: user_model.UserMembershipSearchKeyUserID, + Method: global_model.SearchMethodEquals, + Value: ctxData.UserID, + }, + { + Key: user_model.UserMembershipSearchKeyResourceOwner, + Method: global_model.SearchMethodEquals, + Value: ctxData.OrgID, + }, + }, + }) + if err != nil { + return nil, err + } + iamMemberships, iamCount, err := repo.View.SearchUserMemberships(&user_model.UserMembershipSearchRequest{ + Queries: []*user_model.UserMembershipSearchQuery{ + { + Key: user_model.UserMembershipSearchKeyUserID, + Method: global_model.SearchMethodEquals, + Value: ctxData.UserID, + }, + { + Key: user_model.UserMembershipSearchKeyAggregateID, + Method: global_model.SearchMethodEquals, + Value: repo.IamID, + }, + }, + }) + if err != nil { + return nil, err + } + if orgCount == 0 && iamCount == 0 { + return []*user_view_model.UserMembershipView{}, nil + } + return append(orgMemberships, iamMemberships...), nil +} + func (repo *UserGrantRepo) FillIamProjectID(ctx context.Context) error { if repo.IamProjectID != "" { return nil @@ -79,29 +105,32 @@ func (repo *UserGrantRepo) FillIamProjectID(ctx context.Context) error { return nil } -func mergeOrgAndAdminGrant(ctxData authz.CtxData, orgGrant, iamAdminGrant *model.UserGrantView) (grant *authz.Grant) { - if orgGrant != nil { - roles := orgGrant.RoleKeys - if iamAdminGrant != nil { - roles = addIamAdminRoles(roles, iamAdminGrant.RoleKeys) - } - grant = &authz.Grant{OrgID: orgGrant.ResourceOwner, Roles: roles} - } else if iamAdminGrant != nil { - grant = &authz.Grant{ - OrgID: ctxData.OrgID, - Roles: iamAdminGrant.RoleKeys, +func (repo *UserGrantRepo) mapRoleToPermission(permissions *grant_model.Permissions, membership *user_view_model.UserMembershipView, role string) *grant_model.Permissions { + for _, mapping := range repo.Auth.RolePermissionMappings { + if mapping.Role == role { + ctxID := "" + if membership.MemberType == int32(user_model.MemberTypeProject) || membership.MemberType == int32(user_model.MemberTypeProjectGrant) { + ctxID = membership.ObjectID + } + permissions.AppendPermissions(ctxID, mapping.Permissions...) } } - return grant + return permissions } -func addIamAdminRoles(orgRoles, iamAdminRoles []string) []string { - result := make([]string, 0) - result = append(result, iamAdminRoles...) - for _, role := range orgRoles { - if !authz.ExistsPerm(result, role) { - result = append(result, role) - } +func userMembershipToMembership(membership *user_view_model.UserMembershipView) *authz.Membership { + return &authz.Membership{ + MemberType: authz.MemberType(membership.MemberType), + AggregateID: membership.AggregateID, + ObjectID: membership.ObjectID, + Roles: membership.Roles, + } +} + +func userMembershipsToMemberships(memberships []*user_view_model.UserMembershipView) []*authz.Membership { + result := make([]*authz.Membership, len(memberships)) + for i, m := range memberships { + result[i] = userMembershipToMembership(m) } return result } diff --git a/internal/authz/repository/eventsourcing/handler/handler.go b/internal/authz/repository/eventsourcing/handler/handler.go index ee21d1b02..b18098de1 100644 --- a/internal/authz/repository/eventsourcing/handler/handler.go +++ b/internal/authz/repository/eventsourcing/handler/handler.go @@ -1,6 +1,7 @@ package handler import ( + "github.com/caos/zitadel/internal/iam/repository/eventsourcing" "time" "github.com/caos/zitadel/internal/authz/repository/eventsourcing/view" @@ -8,7 +9,8 @@ import ( "github.com/caos/zitadel/internal/config/types" "github.com/caos/zitadel/internal/eventstore" "github.com/caos/zitadel/internal/eventstore/query" - iam_events "github.com/caos/zitadel/internal/iam/repository/eventsourcing" + org_events "github.com/caos/zitadel/internal/org/repository/eventsourcing" + project_events "github.com/caos/zitadel/internal/project/repository/eventsourcing" ) type Configs map[string]*Config @@ -31,15 +33,21 @@ func (h *handler) Eventstore() eventstore.Eventstore { } type EventstoreRepos struct { - IAMEvents *iam_events.IAMEventstore + IAMEvents *eventsourcing.IAMEventstore + OrgEvents *org_events.OrgEventstore + ProjectEvents *project_events.ProjectEventstore } func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, es eventstore.Eventstore, repos EventstoreRepos, systemDefaults sd.SystemDefaults) []query.Handler { return []query.Handler{ newUserGrant( - handler{view, bulkLimit, configs.cycleDuration("UserGrant"), errorCount, es}, + handler{view, bulkLimit, configs.cycleDuration("UserGrants"), errorCount, es}, repos.IAMEvents, systemDefaults.IamID), + newUserMembership( + handler{view, bulkLimit, configs.cycleDuration("UserMemberships"), errorCount, es}, + repos.OrgEvents, + repos.ProjectEvents), newApplication( handler{view, bulkLimit, configs.cycleDuration("Application"), errorCount, es}), newOrg( diff --git a/internal/authz/repository/eventsourcing/handler/user_membership.go b/internal/authz/repository/eventsourcing/handler/user_membership.go new file mode 100644 index 000000000..4e1b5a81c --- /dev/null +++ b/internal/authz/repository/eventsourcing/handler/user_membership.go @@ -0,0 +1,274 @@ +package handler + +import ( + "context" + + "github.com/caos/logging" + "github.com/caos/zitadel/internal/eventstore" + "github.com/caos/zitadel/internal/eventstore/models" + es_models "github.com/caos/zitadel/internal/eventstore/models" + "github.com/caos/zitadel/internal/eventstore/query" + "github.com/caos/zitadel/internal/eventstore/spooler" + iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" + org_model "github.com/caos/zitadel/internal/org/model" + org_event "github.com/caos/zitadel/internal/org/repository/eventsourcing" + org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" + proj_event "github.com/caos/zitadel/internal/project/repository/eventsourcing" + proj_es_model "github.com/caos/zitadel/internal/project/repository/eventsourcing/model" + usr_model "github.com/caos/zitadel/internal/user/model" + "github.com/caos/zitadel/internal/user/repository/eventsourcing/model" + usr_es_model "github.com/caos/zitadel/internal/user/repository/view/model" +) + +const ( + userMembershipTable = "authz.user_memberships" +) + +type UserMembership struct { + handler + orgEvents *org_event.OrgEventstore + projectEvents *proj_event.ProjectEventstore + subscription *eventstore.Subscription +} + +func newUserMembership( + handler handler, + orgEvents *org_event.OrgEventstore, + projectEvents *proj_event.ProjectEventstore, +) *UserMembership { + h := &UserMembership{ + handler: handler, + orgEvents: orgEvents, + projectEvents: projectEvents, + } + + h.subscribe() + + return h +} + +func (m *UserMembership) subscribe() { + m.subscription = m.es.Subscribe(m.AggregateTypes()...) + go func() { + for event := range m.subscription.Events { + query.ReduceEvent(m, event) + } + }() +} + +func (m *UserMembership) ViewModel() string { + return userMembershipTable +} + +func (_ *UserMembership) AggregateTypes() []es_models.AggregateType { + return []es_models.AggregateType{iam_es_model.IAMAggregate, org_es_model.OrgAggregate, proj_es_model.ProjectAggregate, model.UserAggregate} +} + +func (m *UserMembership) CurrentSequence() (uint64, error) { + sequence, err := m.view.GetLatestUserMembershipSequence() + if err != nil { + return 0, err + } + return sequence.CurrentSequence, nil +} + +func (m *UserMembership) EventQuery() (*models.SearchQuery, error) { + sequence, err := m.view.GetLatestUserMembershipSequence() + if err != nil { + return nil, err + } + return es_models.NewSearchQuery(). + AggregateTypeFilter(m.AggregateTypes()...). + LatestSequenceFilter(sequence.CurrentSequence), nil +} + +func (m *UserMembership) Reduce(event *models.Event) (err error) { + switch event.AggregateType { + case iam_es_model.IAMAggregate: + err = m.processIAM(event) + case org_es_model.OrgAggregate: + err = m.processOrg(event) + case proj_es_model.ProjectAggregate: + err = m.processProject(event) + case model.UserAggregate: + err = m.processUser(event) + } + return err +} + +func (m *UserMembership) processIAM(event *models.Event) (err error) { + member := new(usr_es_model.UserMembershipView) + err = member.AppendEvent(event) + if err != nil { + return err + } + switch event.Type { + case iam_es_model.IAMMemberAdded: + m.fillIamDisplayName(member) + case iam_es_model.IAMMemberChanged: + member, err = m.view.UserMembershipByIDs(member.UserID, event.AggregateID, event.AggregateID, usr_model.MemberTypeIam) + if err != nil { + return err + } + err = member.AppendEvent(event) + case iam_es_model.IAMMemberRemoved: + return m.view.DeleteUserMembership(member.UserID, event.AggregateID, event.AggregateID, usr_model.MemberTypeIam, event) + default: + return m.view.ProcessedUserMembershipSequence(event) + } + if err != nil { + return err + } + return m.view.PutUserMembership(member, event) +} + +func (m *UserMembership) fillIamDisplayName(member *usr_es_model.UserMembershipView) { + member.DisplayName = member.AggregateID + member.ResourceOwnerName = member.ResourceOwner +} + +func (m *UserMembership) processOrg(event *models.Event) (err error) { + member := new(usr_es_model.UserMembershipView) + err = member.AppendEvent(event) + if err != nil { + return err + } + switch event.Type { + case org_es_model.OrgMemberAdded: + err = m.fillOrgName(member) + case org_es_model.OrgMemberChanged: + member, err = m.view.UserMembershipByIDs(member.UserID, event.AggregateID, event.AggregateID, usr_model.MemberTypeOrganisation) + if err != nil { + return err + } + err = member.AppendEvent(event) + case org_es_model.OrgMemberRemoved: + return m.view.DeleteUserMembership(member.UserID, event.AggregateID, event.AggregateID, usr_model.MemberTypeOrganisation, event) + case org_es_model.OrgChanged: + return m.updateOrgName(event) + default: + return m.view.ProcessedUserMembershipSequence(event) + } + if err != nil { + return err + } + return m.view.PutUserMembership(member, event) +} + +func (m *UserMembership) fillOrgName(member *usr_es_model.UserMembershipView) (err error) { + org, err := m.orgEvents.OrgByID(context.Background(), org_model.NewOrg(member.ResourceOwner)) + if err != nil { + return err + } + member.ResourceOwnerName = org.Name + if member.AggregateID == org.AggregateID { + member.DisplayName = org.Name + } + return nil +} + +func (m *UserMembership) updateOrgName(event *models.Event) error { + org, err := m.orgEvents.OrgByID(context.Background(), org_model.NewOrg(event.AggregateID)) + if err != nil { + return err + } + + memberships, err := m.view.UserMembershipsByResourceOwner(event.ResourceOwner) + if err != nil { + return err + } + for _, membership := range memberships { + membership.ResourceOwnerName = org.Name + if membership.AggregateID == event.AggregateID { + membership.DisplayName = org.Name + } + } + return m.view.BulkPutUserMemberships(memberships, event) +} + +func (m *UserMembership) processProject(event *models.Event) (err error) { + member := new(usr_es_model.UserMembershipView) + err = member.AppendEvent(event) + if err != nil { + return err + } + switch event.Type { + case proj_es_model.ProjectMemberAdded, proj_es_model.ProjectGrantMemberAdded: + err = m.fillProjectDisplayName(member) + if err != nil { + return err + } + err = m.fillOrgName(member) + case proj_es_model.ProjectMemberChanged: + member, err = m.view.UserMembershipByIDs(member.UserID, event.AggregateID, event.AggregateID, usr_model.MemberTypeProject) + if err != nil { + return err + } + err = member.AppendEvent(event) + case proj_es_model.ProjectMemberRemoved: + return m.view.DeleteUserMembership(member.UserID, event.AggregateID, event.AggregateID, usr_model.MemberTypeProject, event) + case proj_es_model.ProjectGrantMemberChanged: + member, err = m.view.UserMembershipByIDs(member.UserID, event.AggregateID, member.ObjectID, usr_model.MemberTypeProjectGrant) + if err != nil { + return err + } + err = member.AppendEvent(event) + case proj_es_model.ProjectGrantMemberRemoved: + return m.view.DeleteUserMembership(member.UserID, event.AggregateID, member.ObjectID, usr_model.MemberTypeProjectGrant, event) + case proj_es_model.ProjectChanged: + return m.updateProjectDisplayName(event) + case proj_es_model.ProjectRemoved: + return m.view.DeleteUserMembershipsByAggregateID(event.AggregateID, event) + case proj_es_model.ProjectGrantRemoved: + return m.view.DeleteUserMembershipsByAggregateIDAndObjectID(event.AggregateID, member.ObjectID, event) + default: + return m.view.ProcessedUserMembershipSequence(event) + } + if err != nil { + return err + } + return m.view.PutUserMembership(member, event) +} + +func (m *UserMembership) fillProjectDisplayName(member *usr_es_model.UserMembershipView) (err error) { + project, err := m.projectEvents.ProjectByID(context.Background(), member.AggregateID) + if err != nil { + return err + } + member.DisplayName = project.Name + return nil +} + +func (m *UserMembership) updateProjectDisplayName(event *models.Event) error { + project, err := m.projectEvents.ProjectByID(context.Background(), event.AggregateID) + if err != nil { + return err + } + + memberships, err := m.view.UserMembershipsByAggregateID(event.AggregateID) + if err != nil { + return err + } + for _, membership := range memberships { + membership.DisplayName = project.Name + } + return m.view.BulkPutUserMemberships(memberships, event) +} + +func (m *UserMembership) processUser(event *models.Event) (err error) { + switch event.Type { + case model.UserRemoved: + return m.view.DeleteUserMembershipsByUserID(event.AggregateID, event) + default: + return m.view.ProcessedUserMembershipSequence(event) + } +} + +func (m *UserMembership) OnError(event *models.Event, err error) error { + logging.LogWithFields("SPOOL-Ms3fj", "id", event.AggregateID).WithError(err).Warn("something went wrong in user membership handler") + return spooler.HandleError(event, err, m.view.GetLatestUserMembershipFailedEvent, m.view.ProcessedUserMembershipFailedEvent, m.view.ProcessedUserMembershipSequence, m.errorCountUntilSkip) +} + +func (m *UserMembership) OnSuccess() error { + return spooler.HandleSuccess(m.view.UpdateUserMembershipSpoolerRunTimestamp) +} diff --git a/internal/authz/repository/eventsourcing/repository.go b/internal/authz/repository/eventsourcing/repository.go index 3a107c834..73821aa71 100644 --- a/internal/authz/repository/eventsourcing/repository.go +++ b/internal/authz/repository/eventsourcing/repository.go @@ -3,6 +3,7 @@ package eventsourcing import ( "context" "github.com/caos/zitadel/internal/v2/query" + es_org "github.com/caos/zitadel/internal/org/repository/eventsourcing" es_user "github.com/caos/zitadel/internal/user/repository/eventsourcing" @@ -22,6 +23,7 @@ import ( ) type Config struct { + Domain string Eventstore es_int.Config AuthRequest cache.Config View types.SQL @@ -60,6 +62,8 @@ func Start(conf Config, authZ authz.Config, systemDefaults sd.SystemDefaults) (* if err != nil { return nil, err } + org := es_org.StartOrg(es_org.OrgConfig{Eventstore: es, IAMDomain: conf.Domain}, systemDefaults) + project, err := es_proj.StartProject(es_proj.ProjectConfig{ Eventstore: es, Cache: conf.Eventstore.Cache, @@ -82,7 +86,7 @@ func Start(conf Config, authZ authz.Config, systemDefaults sd.SystemDefaults) (* return nil, err } - repos := handler.EventstoreRepos{IAMEvents: iam} + repos := handler.EventstoreRepos{IAMEvents: iam, OrgEvents: org, ProjectEvents: project} spool := spooler.StartSpooler(conf.Spooler, es, view, sqlClient, repos, systemDefaults) return &EsRepository{ diff --git a/internal/authz/repository/eventsourcing/view/user_membership.go b/internal/authz/repository/eventsourcing/view/user_membership.go new file mode 100644 index 000000000..add7b3aa8 --- /dev/null +++ b/internal/authz/repository/eventsourcing/view/user_membership.go @@ -0,0 +1,98 @@ +package view + +import ( + "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/eventstore/models" + usr_model "github.com/caos/zitadel/internal/user/model" + "github.com/caos/zitadel/internal/user/repository/view" + "github.com/caos/zitadel/internal/user/repository/view/model" + "github.com/caos/zitadel/internal/view/repository" +) + +const ( + userMembershipTable = "authz.user_memberships" +) + +func (v *View) UserMembershipByIDs(userID, aggregateID, objectID string, memberType usr_model.MemberType) (*model.UserMembershipView, error) { + return view.UserMembershipByIDs(v.Db, userMembershipTable, userID, aggregateID, objectID, memberType) +} + +func (v *View) UserMembershipsByAggregateID(aggregateID string) ([]*model.UserMembershipView, error) { + return view.UserMembershipsByAggregateID(v.Db, userMembershipTable, aggregateID) +} + +func (v *View) UserMembershipsByResourceOwner(resourceOwner string) ([]*model.UserMembershipView, error) { + return view.UserMembershipsByResourceOwner(v.Db, userMembershipTable, resourceOwner) +} + +func (v *View) SearchUserMemberships(request *usr_model.UserMembershipSearchRequest) ([]*model.UserMembershipView, uint64, error) { + return view.SearchUserMemberships(v.Db, userMembershipTable, request) +} + +func (v *View) PutUserMembership(membership *model.UserMembershipView, event *models.Event) error { + err := view.PutUserMembership(v.Db, userMembershipTable, membership) + if err != nil { + return err + } + return v.ProcessedUserMembershipSequence(event) +} + +func (v *View) BulkPutUserMemberships(memberships []*model.UserMembershipView, event *models.Event) error { + err := view.PutUserMemberships(v.Db, userMembershipTable, memberships...) + if err != nil { + return err + } + return v.ProcessedUserMembershipSequence(event) +} + +func (v *View) DeleteUserMembership(userID, aggregateID, objectID string, memberType usr_model.MemberType, event *models.Event) error { + err := view.DeleteUserMembership(v.Db, userMembershipTable, userID, aggregateID, objectID, memberType) + if err != nil && !errors.IsNotFound(err) { + return err + } + return v.ProcessedUserMembershipSequence(event) +} + +func (v *View) DeleteUserMembershipsByUserID(userID string, event *models.Event) error { + err := view.DeleteUserMembershipsByUserID(v.Db, userMembershipTable, userID) + if err != nil && !errors.IsNotFound(err) { + return err + } + return v.ProcessedUserMembershipSequence(event) +} + +func (v *View) DeleteUserMembershipsByAggregateID(aggregateID string, event *models.Event) error { + err := view.DeleteUserMembershipsByAggregateID(v.Db, userMembershipTable, aggregateID) + if err != nil && !errors.IsNotFound(err) { + return err + } + return v.ProcessedUserMembershipSequence(event) +} + +func (v *View) DeleteUserMembershipsByAggregateIDAndObjectID(aggregateID, objectID string, event *models.Event) error { + err := view.DeleteUserMembershipsByAggregateIDAndObjectID(v.Db, userMembershipTable, aggregateID, objectID) + if err != nil && !errors.IsNotFound(err) { + return err + } + return v.ProcessedUserMembershipSequence(event) +} + +func (v *View) GetLatestUserMembershipSequence() (*repository.CurrentSequence, error) { + return v.latestSequence(userMembershipTable) +} + +func (v *View) ProcessedUserMembershipSequence(event *models.Event) error { + return v.saveCurrentSequence(userMembershipTable, event) +} + +func (v *View) UpdateUserMembershipSpoolerRunTimestamp() error { + return v.updateSpoolerRunSequence(userMembershipTable) +} + +func (v *View) GetLatestUserMembershipFailedEvent(sequence uint64) (*repository.FailedEvent, error) { + return v.latestFailedEvent(userMembershipTable, sequence) +} + +func (v *View) ProcessedUserMembershipFailedEvent(failedEvent *repository.FailedEvent) error { + return v.saveFailedEvent(failedEvent) +} diff --git a/internal/config/systemdefaults/system_defaults.go b/internal/config/systemdefaults/system_defaults.go index 8f47681ff..b623aad37 100644 --- a/internal/config/systemdefaults/system_defaults.go +++ b/internal/config/systemdefaults/system_defaults.go @@ -40,6 +40,7 @@ type SecretGenerators struct { PhoneVerificationCode crypto.GeneratorConfig PasswordVerificationCode crypto.GeneratorConfig MachineKeySize uint32 + ClientKeySize uint32 } type MultifactorConfig struct { diff --git a/internal/iam/repository/eventsourcing/eventstore_test.go b/internal/iam/repository/eventsourcing/eventstore_test.go index e6c304ef6..a32efc076 100644 --- a/internal/iam/repository/eventsourcing/eventstore_test.go +++ b/internal/iam/repository/eventsourcing/eventstore_test.go @@ -3061,3 +3061,321 @@ func TestChangeMailText(t *testing.T) { }) } } +func TestAddMailTemplate(t *testing.T) { + ctrl := gomock.NewController(t) + type args struct { + es *IAMEventstore + ctx context.Context + policy *iam_model.MailTemplate + } + type res struct { + result *iam_model.MailTemplate + wantErr bool + errFunc func(err error) bool + } + tests := []struct { + name string + args args + res res + }{ + { + name: "add mailtemplate, ok", + args: args{ + es: GetMockManipulateIAM(ctrl), + ctx: authz.NewMockContext("orgID", "userID"), + policy: &iam_model.MailTemplate{ + ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, + Template: []byte(""), + }, + }, + res: res{ + result: &iam_model.MailTemplate{ + ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, + Template: []byte(""), + }, + }, + }, + { + name: "invalid policy", + args: args{ + es: GetMockManipulateIAM(ctrl), + ctx: authz.NewMockContext("orgID", "userID"), + policy: &iam_model.MailTemplate{ + ObjectRoot: es_models.ObjectRoot{Sequence: 0}, + }, + }, + res: res{ + wantErr: true, + errFunc: caos_errs.IsPreconditionFailed, + }, + }, + { + name: "existing iam not found", + args: args{ + es: GetMockManipulateIAMNotExisting(ctrl), + ctx: authz.NewMockContext("orgID", "userID"), + policy: &iam_model.MailTemplate{ + ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, + }, + }, + res: res{ + wantErr: true, + errFunc: caos_errs.IsNotFound, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result, err := tt.args.es.AddMailTemplate(tt.args.ctx, tt.args.policy) + if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { + t.Errorf("got wrong err: %v ", err) + return + } + if tt.res.wantErr && tt.res.errFunc(err) { + return + } + if string(result.Template) != string(tt.res.result.Template) { + t.Errorf("got wrong result Template: expected: %v, actual: %v ", tt.res.result.Template, result.Template) + } + }) + } +} + +func TestChangeMailTemplate(t *testing.T) { + ctrl := gomock.NewController(t) + type args struct { + es *IAMEventstore + ctx context.Context + template *iam_model.MailTemplate + } + type res struct { + result *iam_model.MailTemplate + wantErr bool + errFunc func(err error) bool + } + tests := []struct { + name string + args args + res res + }{ + { + name: "add mail template, ok", + args: args{ + es: GetMockManipulateIAMWithMailTemplate(ctrl), + ctx: authz.NewMockContext("orgID", "userID"), + template: &iam_model.MailTemplate{ + ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, + Template: []byte(""), + }, + }, + res: res{ + result: &iam_model.MailTemplate{ + ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, + Template: []byte(""), + }, + }, + }, + { + name: "invalid mail template", + args: args{ + es: GetMockManipulateIAM(ctrl), + ctx: authz.NewMockContext("orgID", "userID"), + template: &iam_model.MailTemplate{ + ObjectRoot: es_models.ObjectRoot{Sequence: 0}, + }, + }, + res: res{ + wantErr: true, + errFunc: caos_errs.IsPreconditionFailed, + }, + }, + { + name: "existing iam not found", + args: args{ + es: GetMockManipulateIAMNotExisting(ctrl), + ctx: authz.NewMockContext("orgID", "userID"), + template: &iam_model.MailTemplate{ + ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, + }, + }, + res: res{ + wantErr: true, + errFunc: caos_errs.IsNotFound, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result, err := tt.args.es.ChangeMailTemplate(tt.args.ctx, tt.args.template) + if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { + t.Errorf("got wrong err: %v ", err) + return + } + if tt.res.wantErr && tt.res.errFunc(err) { + return + } + if string(result.Template) != string(tt.res.result.Template) { + t.Errorf("got wrong result Template: expected: %v, actual: %v ", tt.res.result.Template, result.Template) + } + }) + } +} +func TestAddMailText(t *testing.T) { + ctrl := gomock.NewController(t) + type args struct { + es *IAMEventstore + ctx context.Context + policy *iam_model.MailText + } + type res struct { + result *iam_model.MailText + wantErr bool + errFunc func(err error) bool + } + tests := []struct { + name string + args args + res res + }{ + { + name: "add mailtemplate, ok", + args: args{ + es: GetMockManipulateIAM(ctrl), + ctx: authz.NewMockContext("orgID", "userID"), + policy: &iam_model.MailText{ + ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, + MailTextType: "Type", Language: "DE", + }, + }, + res: res{ + result: &iam_model.MailText{ + ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, + MailTextType: "Type", Language: "DE", + }, + }, + }, + { + name: "invalid policy", + args: args{ + es: GetMockManipulateIAM(ctrl), + ctx: authz.NewMockContext("orgID", "userID"), + policy: &iam_model.MailText{ + ObjectRoot: es_models.ObjectRoot{Sequence: 0}, + }, + }, + res: res{ + wantErr: true, + errFunc: caos_errs.IsPreconditionFailed, + }, + }, + { + name: "existing iam not found", + args: args{ + es: GetMockManipulateIAMNotExisting(ctrl), + ctx: authz.NewMockContext("orgID", "userID"), + policy: &iam_model.MailText{ + ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, + }, + }, + res: res{ + wantErr: true, + errFunc: caos_errs.IsNotFound, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result, err := tt.args.es.AddMailText(tt.args.ctx, tt.args.policy) + if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { + t.Errorf("got wrong err: %v ", err) + return + } + if tt.res.wantErr && tt.res.errFunc(err) { + return + } + if string(result.MailTextType) != string(tt.res.result.MailTextType) { + t.Errorf("got wrong result MailTextType: expected: %v, actual: %v ", tt.res.result.MailTextType, result.MailTextType) + } + }) + } +} + +func TestChangeMailText(t *testing.T) { + ctrl := gomock.NewController(t) + type args struct { + es *IAMEventstore + ctx context.Context + policy *iam_model.MailText + } + type res struct { + result *iam_model.MailText + wantErr bool + errFunc func(err error) bool + } + tests := []struct { + name string + args args + res res + }{ + { + name: "change mailtemplate, ok", + args: args{ + es: GetMockManipulateIAMWithMailText(ctrl), + ctx: authz.NewMockContext("orgID", "userID"), + policy: &iam_model.MailText{ + ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, + MailTextType: "Type", Language: "DE", + }, + }, + res: res{ + result: &iam_model.MailText{ + ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, + MailTextType: "Type", Language: "DE", + }, + }, + }, + { + name: "invalid policy", + args: args{ + es: GetMockManipulateIAM(ctrl), + ctx: authz.NewMockContext("orgID", "userID"), + policy: &iam_model.MailText{ + ObjectRoot: es_models.ObjectRoot{Sequence: 0}, + }, + }, + res: res{ + wantErr: true, + errFunc: caos_errs.IsPreconditionFailed, + }, + }, + { + name: "existing iam not found", + args: args{ + es: GetMockManipulateIAMNotExisting(ctrl), + ctx: authz.NewMockContext("orgID", "userID"), + policy: &iam_model.MailText{ + ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, + }, + }, + res: res{ + wantErr: true, + errFunc: caos_errs.IsNotFound, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result, err := tt.args.es.ChangeMailText(tt.args.ctx, tt.args.policy) + if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { + t.Errorf("got wrong err: %v ", err) + return + } + if tt.res.wantErr && tt.res.errFunc(err) { + return + } + if string(result.MailTextType) != string(tt.res.result.MailTextType) { + t.Errorf("got wrong result MailTextType: expected: %v, actual: %v ", tt.res.result.MailTextType, result.MailTextType) + } + }) + } +} diff --git a/internal/iam/repository/eventsourcing/model/iam.go b/internal/iam/repository/eventsourcing/model/iam.go index 23478dfdb..f67bb55ed 100644 --- a/internal/iam/repository/eventsourcing/model/iam.go +++ b/internal/iam/repository/eventsourcing/model/iam.go @@ -83,13 +83,13 @@ func IAMToModel(iam *IAM) *model.IAM { idps := IDPConfigsToModel(iam.IDPs) mailTexts := MailTextsToModel(iam.DefaultMailTexts) converted := &model.IAM{ - ObjectRoot: iam.ObjectRoot, - SetUpStarted: domain.Step(iam.SetUpStarted), - SetUpDone: domain.Step(iam.SetUpDone), - GlobalOrgID: iam.GlobalOrgID, - IAMProjectID: iam.IAMProjectID, - Members: members, - IDPs: idps, + ObjectRoot: iam.ObjectRoot, + SetUpStarted: domain.Step(iam.SetUpStarted), + SetUpDone: domain.Step(iam.SetUpDone), + GlobalOrgID: iam.GlobalOrgID, + IAMProjectID: iam.IAMProjectID, + Members: members, + IDPs: idps, DefaultMailTexts: mailTexts, } if iam.DefaultLoginPolicy != nil { diff --git a/internal/key/model/authn_key.go b/internal/key/model/authn_key.go new file mode 100644 index 000000000..417c812a3 --- /dev/null +++ b/internal/key/model/authn_key.go @@ -0,0 +1,101 @@ +package model + +import ( + "time" + + "github.com/caos/zitadel/internal/eventstore/models" + "github.com/caos/zitadel/internal/model" +) + +const ( + yearLayout = "2006-01-02" + defaultExpirationDate = "9999-01-01" +) + +type AuthNKeyView struct { + ID string + ObjectID string + ObjectType ObjectType + AuthIdentifier string + Type AuthNKeyType + Sequence uint64 + CreationDate time.Time + ExpirationDate time.Time + PublicKey []byte + State AuthNKeyState +} + +type AuthNKey struct { + models.ObjectRoot + + KeyID string + ObjectType ObjectType + Type AuthNKeyType + ExpirationDate time.Time + PrivateKey []byte +} + +type AuthNKeyType int32 + +const ( + AuthNKeyTypeNONE = iota + AuthNKeyTypeJSON +) + +type AuthNKeyState int32 + +const ( + AuthNKeyStateActive AuthNKeyState = iota + AuthNKeyStateInactive + AuthNKeyStateRemoved +) + +type AuthNKeySearchRequest struct { + Offset uint64 + Limit uint64 + SortingColumn AuthNKeySearchKey + Asc bool + Queries []*AuthNKeySearchQuery +} + +type AuthNKeySearchKey int32 + +const ( + AuthNKeyKeyUnspecified AuthNKeySearchKey = iota + AuthNKeyKeyID + AuthNKeyObjectID + AuthNKeyObjectType +) + +type ObjectType int32 + +const ( + AuthNKeyObjectTypeUnspecified ObjectType = iota + AuthNKeyObjectTypeUser + AuthNKeyObjectTypeApplication +) + +type AuthNKeySearchQuery struct { + Key AuthNKeySearchKey + Method model.SearchMethod + Value interface{} +} + +type AuthNKeySearchResponse struct { + Offset uint64 + Limit uint64 + TotalResult uint64 + Result []*AuthNKeyView + Sequence uint64 + Timestamp time.Time +} + +func (r *AuthNKeySearchRequest) EnsureLimit(limit uint64) { + if r.Limit == 0 || r.Limit > limit { + r.Limit = limit + } +} + +func DefaultExpiration() (time.Time, error) { + return time.Parse(yearLayout, defaultExpirationDate) +} diff --git a/internal/key/repository/view/authn_key_view.go b/internal/key/repository/view/authn_key_view.go new file mode 100644 index 000000000..5bd299150 --- /dev/null +++ b/internal/key/repository/view/authn_key_view.go @@ -0,0 +1,77 @@ +package view + +import ( + caos_errs "github.com/caos/zitadel/internal/errors" + key_model "github.com/caos/zitadel/internal/key/model" + "github.com/caos/zitadel/internal/key/repository/view/model" + global_model "github.com/caos/zitadel/internal/model" + "github.com/caos/zitadel/internal/view/repository" + "github.com/jinzhu/gorm" +) + +func AuthNKeyByIDs(db *gorm.DB, table, objectID, keyID string) (*model.AuthNKeyView, error) { + key := new(model.AuthNKeyView) + query := repository.PrepareGetByQuery(table, + model.AuthNKeySearchQuery{Key: key_model.AuthNKeyObjectID, Method: global_model.SearchMethodEquals, Value: objectID}, + model.AuthNKeySearchQuery{Key: key_model.AuthNKeyKeyID, Method: global_model.SearchMethodEquals, Value: keyID}, + ) + err := query(db, key) + if caos_errs.IsNotFound(err) { + return nil, caos_errs.ThrowNotFound(nil, "VIEW-3Dk9s", "Errors.User.KeyNotFound") + } + return key, err +} + +func SearchAuthNKeys(db *gorm.DB, table string, req *key_model.AuthNKeySearchRequest) ([]*model.AuthNKeyView, uint64, error) { + keys := make([]*model.AuthNKeyView, 0) + query := repository.PrepareSearchQuery(table, model.AuthNKeySearchRequest{Limit: req.Limit, Offset: req.Offset, Queries: req.Queries}) + count, err := query(db, &keys) + if err != nil { + return nil, 0, err + } + return keys, count, nil +} + +func AuthNKeysByObjectID(db *gorm.DB, table string, objectID string) ([]*model.AuthNKeyView, error) { + keys := make([]*model.AuthNKeyView, 0) + queries := []*key_model.AuthNKeySearchQuery{ + { + Key: key_model.AuthNKeyObjectID, + Value: objectID, + Method: global_model.SearchMethodEquals, + }, + } + query := repository.PrepareSearchQuery(table, model.AuthNKeySearchRequest{Queries: queries}) + _, err := query(db, &keys) + if err != nil { + return nil, err + } + return keys, nil +} + +func AuthNKeyByID(db *gorm.DB, table string, keyID string) (*model.AuthNKeyView, error) { + key := new(model.AuthNKeyView) + query := repository.PrepareGetByQuery(table, + model.AuthNKeySearchQuery{Key: key_model.AuthNKeyKeyID, Method: global_model.SearchMethodEquals, Value: keyID}, + ) + err := query(db, key) + if caos_errs.IsNotFound(err) { + return nil, caos_errs.ThrowNotFound(nil, "VIEW-BjN6x", "Errors.User.KeyNotFound") + } + return key, err +} + +func PutAuthNKey(db *gorm.DB, table string, role *model.AuthNKeyView) error { + save := repository.PrepareSave(table) + return save(db, role) +} + +func DeleteAuthNKey(db *gorm.DB, table, keyID string) error { + delete := repository.PrepareDeleteByKey(table, model.AuthNKeySearchKey(key_model.AuthNKeyKeyID), keyID) + return delete(db) +} + +func DeleteAuthNKeysByObjectID(db *gorm.DB, table, objectID string) error { + delete := repository.PrepareDeleteByKey(table, model.AuthNKeySearchKey(key_model.AuthNKeyObjectID), objectID) + return delete(db) +} diff --git a/internal/key/repository/view/model/authn_key.go b/internal/key/repository/view/model/authn_key.go new file mode 100644 index 000000000..200c5b36b --- /dev/null +++ b/internal/key/repository/view/model/authn_key.go @@ -0,0 +1,171 @@ +package model + +import ( + "encoding/json" + "time" + + "github.com/caos/logging" + + caos_errs "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/eventstore/models" + "github.com/caos/zitadel/internal/key/model" + proj_model "github.com/caos/zitadel/internal/project/repository/eventsourcing/model" + proj_view_model "github.com/caos/zitadel/internal/project/repository/view/model" + user_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model" +) + +const ( + AuthNKeyKeyID = "key_id" + AuthNKeyObjectID = "object_id" + AuthNKeyObjectType = "object_type" +) + +type AuthNKeyView struct { + ID string `json:"keyId" gorm:"column:key_id;primary_key"` + ObjectID string `json:"-" gorm:"column:object_id;primary_key"` + ObjectType int32 `json:"-" gorm:"column:object_type;primary_key"` + AuthIdentifier string `json:"-" gorm:"column:auth_identifier;primary_key"` + Type int32 `json:"type" gorm:"column:key_type"` + ExpirationDate time.Time `json:"expirationDate" gorm:"column:expiration_date"` + Sequence uint64 `json:"-" gorm:"column:sequence"` + CreationDate time.Time `json:"-" gorm:"column:creation_date"` + PublicKey []byte `json:"publicKey" gorm:"column:public_key"` + State int32 `json:"-" gorm:"column:state"` +} + +func AuthNKeyViewFromModel(key *model.AuthNKeyView) *AuthNKeyView { + return &AuthNKeyView{ + ID: key.ID, + ObjectID: key.ObjectID, + ObjectType: int32(key.ObjectType), + Type: int32(key.Type), + ExpirationDate: key.ExpirationDate, + Sequence: key.Sequence, + CreationDate: key.CreationDate, + State: int32(key.State), + } +} + +func AuthNKeyToModel(key *AuthNKeyView) *model.AuthNKeyView { + return &model.AuthNKeyView{ + ID: key.ID, + ObjectID: key.ObjectID, + ObjectType: model.ObjectType(key.ObjectType), + AuthIdentifier: key.AuthIdentifier, + Type: model.AuthNKeyType(key.Type), + ExpirationDate: key.ExpirationDate, + Sequence: key.Sequence, + CreationDate: key.CreationDate, + PublicKey: key.PublicKey, + State: model.AuthNKeyState(key.State), + } +} + +func AuthNKeysToModel(keys []*AuthNKeyView) []*model.AuthNKeyView { + result := make([]*model.AuthNKeyView, len(keys)) + for i, key := range keys { + result[i] = AuthNKeyToModel(key) + } + return result +} + +func (k *AuthNKeyView) AppendEventIfMyClientKey(event *models.Event) (err error) { + switch event.Type { + case proj_model.ApplicationDeactivated, + proj_model.ApplicationReactivated, + proj_model.ApplicationRemoved: + a := new(proj_view_model.ApplicationView) + if err := a.AppendEvent(event); err != nil { + return err + } + if a.ID == k.ObjectID { + return k.AppendEvent(event) + } + case proj_model.ProjectDeactivated, + proj_model.ProjectReactivated, + proj_model.ProjectRemoved: + return k.AppendEvent(event) + case user_model.UserLocked, + user_model.UserDeactivated, + user_model.UserUnlocked, + user_model.UserReactivated, + user_model.UserRemoved: + return k.AppendEvent(event) + case proj_model.ClientKeyRemoved, + user_model.MachineKeyRemoved: + view := new(AuthNKeyView) + if view.ID == k.ID { + return k.AppendEvent(event) + } + default: + return nil + } + return nil +} + +func (k *AuthNKeyView) AppendEvent(event *models.Event) (err error) { + k.Sequence = event.Sequence + switch event.Type { + case user_model.MachineKeyAdded: + k.setRootData(event) + k.CreationDate = event.CreationDate + err = k.SetUserData(event) + case proj_model.ClientKeyAdded: + k.setRootData(event) + k.CreationDate = event.CreationDate + err = k.SetClientData(event) + case proj_model.ClientKeyRemoved, + proj_model.ApplicationRemoved, + proj_model.ProjectRemoved, + user_model.MachineKeyRemoved, + user_model.UserRemoved: + k.State = int32(model.AuthNKeyStateRemoved) + case proj_model.ProjectDeactivated, + proj_model.ApplicationDeactivated, + user_model.UserDeactivated, + user_model.UserLocked: + k.State = int32(model.AuthNKeyStateInactive) + case proj_model.ProjectReactivated, + proj_model.ApplicationReactivated, + user_model.UserReactivated, + user_model.UserUnlocked: + if k.State != int32(model.AuthNKeyStateRemoved) { + k.State = int32(model.AuthNKeyStateActive) + } + } + return err +} + +func (k *AuthNKeyView) setRootData(event *models.Event) { + switch event.AggregateType { + case user_model.UserAggregate: + k.ObjectType = int32(model.AuthNKeyObjectTypeUser) + k.ObjectID = event.AggregateID + k.AuthIdentifier = event.AggregateID + case proj_model.ProjectAggregate: + k.ObjectType = int32(model.AuthNKeyObjectTypeApplication) + } +} + +func (k *AuthNKeyView) SetUserData(event *models.Event) error { + if err := json.Unmarshal(event.Data, k); err != nil { + logging.Log("EVEN-Sj90d").WithError(err).Error("could not unmarshal event data") + return caos_errs.ThrowInternal(err, "MODEL-lub6s", "Could not unmarshal data") + } + return nil +} + +func (k *AuthNKeyView) SetClientData(event *models.Event) error { + key := new(proj_model.ClientKey) + if err := json.Unmarshal(event.Data, key); err != nil { + logging.Log("EVEN-Dgsgg").WithError(err).Error("could not unmarshal event data") + return caos_errs.ThrowInternal(err, "MODEL-ADbfz", "Could not unmarshal data") + } + k.ObjectID = key.ApplicationID + k.AuthIdentifier = key.ClientID + k.ID = key.KeyID + k.ExpirationDate = key.ExpirationDate + k.PublicKey = key.PublicKey + k.Type = key.Type + return nil +} diff --git a/internal/key/repository/view/model/authn_key_query.go b/internal/key/repository/view/model/authn_key_query.go new file mode 100644 index 000000000..e26c58977 --- /dev/null +++ b/internal/key/repository/view/model/authn_key_query.go @@ -0,0 +1,63 @@ +package model + +import ( + key_model "github.com/caos/zitadel/internal/key/model" + global_model "github.com/caos/zitadel/internal/model" + "github.com/caos/zitadel/internal/view/repository" +) + +type AuthNKeySearchRequest key_model.AuthNKeySearchRequest +type AuthNKeySearchQuery key_model.AuthNKeySearchQuery +type AuthNKeySearchKey key_model.AuthNKeySearchKey + +func (req AuthNKeySearchRequest) GetLimit() uint64 { + return req.Limit +} + +func (req AuthNKeySearchRequest) GetOffset() uint64 { + return req.Offset +} + +func (req AuthNKeySearchRequest) GetSortingColumn() repository.ColumnKey { + if req.SortingColumn == key_model.AuthNKeyKeyUnspecified { + return nil + } + return AuthNKeySearchKey(req.SortingColumn) +} + +func (req AuthNKeySearchRequest) GetAsc() bool { + return req.Asc +} + +func (req AuthNKeySearchRequest) GetQueries() []repository.SearchQuery { + result := make([]repository.SearchQuery, len(req.Queries)) + for i, q := range req.Queries { + result[i] = AuthNKeySearchQuery{Key: q.Key, Value: q.Value, Method: q.Method} + } + return result +} + +func (req AuthNKeySearchQuery) GetKey() repository.ColumnKey { + return AuthNKeySearchKey(req.Key) +} + +func (req AuthNKeySearchQuery) GetMethod() global_model.SearchMethod { + return req.Method +} + +func (req AuthNKeySearchQuery) GetValue() interface{} { + return req.Value +} + +func (key AuthNKeySearchKey) ToColumnName() string { + switch key_model.AuthNKeySearchKey(key) { + case key_model.AuthNKeyKeyID: + return AuthNKeyKeyID + case key_model.AuthNKeyObjectID: + return AuthNKeyObjectID + case key_model.AuthNKeyObjectType: + return AuthNKeyObjectType + default: + return "" + } +} diff --git a/internal/management/repository/eventsourcing/eventstore/permissions.go b/internal/management/repository/eventsourcing/eventstore/permissions.go index 14f3981e4..653792a53 100644 --- a/internal/management/repository/eventsourcing/eventstore/permissions.go +++ b/internal/management/repository/eventsourcing/eventstore/permissions.go @@ -5,5 +5,5 @@ const ( orgMemberReadPerm = "org.member.read" iamMemberReadPerm = "iam.member.read" projectMemberReadPerm = "project.member.read" - projectGrantMemberReadPerm = "project.member.read" + projectGrantMemberReadPerm = "project.grant.member.read" ) diff --git a/internal/management/repository/eventsourcing/eventstore/project.go b/internal/management/repository/eventsourcing/eventstore/project.go index 3c7eb5773..0324efdbb 100644 --- a/internal/management/repository/eventsourcing/eventstore/project.go +++ b/internal/management/repository/eventsourcing/eventstore/project.go @@ -10,6 +10,8 @@ import ( caos_errs "github.com/caos/zitadel/internal/errors" es_int "github.com/caos/zitadel/internal/eventstore" iam_event "github.com/caos/zitadel/internal/iam/repository/eventsourcing" + key_model "github.com/caos/zitadel/internal/key/model" + key_view_model "github.com/caos/zitadel/internal/key/repository/view/model" "github.com/caos/zitadel/internal/management/repository/eventsourcing/view" global_model "github.com/caos/zitadel/internal/model" proj_model "github.com/caos/zitadel/internal/project/model" @@ -227,6 +229,10 @@ func (repo *ProjectRepo) ApplicationByID(ctx context.Context, projectID, appID s return model.ApplicationViewToModel(app), nil } +func (repo *ProjectRepo) AddApplication(ctx context.Context, app *proj_model.Application) (*proj_model.Application, error) { + return repo.ProjectEvents.AddApplication(ctx, app) +} + func (repo *ProjectRepo) SearchApplications(ctx context.Context, request *proj_model.ApplicationSearchRequest) (*proj_model.ApplicationSearchResponse, error) { request.EnsureLimit(repo.SearchLimit) sequence, sequenceErr := repo.View.GetLatestApplicationSequence() @@ -268,10 +274,80 @@ func (repo *ProjectRepo) ApplicationChanges(ctx context.Context, id string, appI return changes, nil } +func (repo *ProjectRepo) SearchClientKeys(ctx context.Context, request *key_model.AuthNKeySearchRequest) (*key_model.AuthNKeySearchResponse, error) { + request.EnsureLimit(repo.SearchLimit) + sequence, sequenceErr := repo.View.GetLatestAuthNKeySequence() + logging.Log("EVENT-ADwgw").OnError(sequenceErr).Warn("could not read latest authn key sequence") + keys, count, err := repo.View.SearchAuthNKeys(request) + if err != nil { + return nil, err + } + result := &key_model.AuthNKeySearchResponse{ + Offset: request.Offset, + Limit: request.Limit, + TotalResult: count, + Result: key_view_model.AuthNKeysToModel(keys), + } + if sequenceErr == nil { + result.Sequence = sequence.CurrentSequence + result.Timestamp = sequence.LastSuccessfulSpoolerRun + } + return result, nil +} + +func (repo *ProjectRepo) GetClientKey(ctx context.Context, projectID, applicationID, keyID string) (*key_model.AuthNKeyView, error) { + key, viewErr := repo.View.AuthNKeyByIDs(applicationID, keyID) + if viewErr != nil { + return nil, viewErr + } + + events, esErr := repo.ProjectEvents.ProjectEventsByID(ctx, projectID, key.Sequence) + if caos_errs.IsNotFound(viewErr) && len(events) == 0 { + return nil, caos_errs.ThrowNotFound(nil, "EVENT-SFf2g", "Errors.User.KeyNotFound") + } + + if esErr != nil { + logging.Log("EVENT-ADbf2").WithError(viewErr).Debug("error retrieving new events") + return key_view_model.AuthNKeyToModel(key), nil + } + + viewKey := *key + for _, event := range events { + err := key.AppendEventIfMyClientKey(event) + if err != nil { + return key_view_model.AuthNKeyToModel(&viewKey), nil + } + if key.State != int32(proj_model.AppStateActive) { + return nil, caos_errs.ThrowNotFound(nil, "EVENT-Adfg3", "Errors.User.KeyNotFound") + } + } + return key_view_model.AuthNKeyToModel(key), nil +} + +func (repo *ProjectRepo) AddClientKey(ctx context.Context, key *proj_model.ClientKey) (*proj_model.ClientKey, error) { + return repo.ProjectEvents.AddClientKey(ctx, key) +} + +func (repo *ProjectRepo) RemoveClientKey(ctx context.Context, projectID, applicationID, keyID string) error { + return repo.ProjectEvents.RemoveApplicationKey(ctx, projectID, applicationID, keyID) +} + +func (repo *ProjectRepo) ChangeOIDCConfig(ctx context.Context, config *proj_model.OIDCConfig) (*proj_model.OIDCConfig, error) { + return repo.ProjectEvents.ChangeOIDCConfig(ctx, config) +} + +func (repo *ProjectRepo) ChangeAPIConfig(ctx context.Context, config *proj_model.APIConfig) (*proj_model.APIConfig, error) { + return repo.ProjectEvents.ChangeAPIConfig(ctx, config) +} + func (repo *ProjectRepo) ChangeOIDConfigSecret(ctx context.Context, projectID, appID string) (*proj_model.OIDCConfig, error) { return repo.ProjectEvents.ChangeOIDCConfigSecret(ctx, projectID, appID) } +func (repo *ProjectRepo) ChangeAPIConfigSecret(ctx context.Context, projectID, appID string) (*proj_model.APIConfig, error) { + return repo.ProjectEvents.ChangeAPIConfigSecret(ctx, projectID, appID) +} + func (repo *ProjectRepo) ProjectGrantByID(ctx context.Context, grantID string) (*proj_model.ProjectGrantView, error) { grant, err := repo.View.ProjectGrantByID(grantID) if err != nil { diff --git a/internal/management/repository/eventsourcing/eventstore/user.go b/internal/management/repository/eventsourcing/eventstore/user.go index 0cf81890b..7588e23f8 100644 --- a/internal/management/repository/eventsourcing/eventstore/user.go +++ b/internal/management/repository/eventsourcing/eventstore/user.go @@ -4,11 +4,14 @@ import ( "context" "github.com/caos/logging" + "github.com/caos/zitadel/internal/api/authz" "github.com/caos/zitadel/internal/config/systemdefaults" "github.com/caos/zitadel/internal/errors" caos_errs "github.com/caos/zitadel/internal/errors" es_int "github.com/caos/zitadel/internal/eventstore" + key_model "github.com/caos/zitadel/internal/key/model" + key_view_model "github.com/caos/zitadel/internal/key/repository/view/model" "github.com/caos/zitadel/internal/management/repository/eventsourcing/view" global_model "github.com/caos/zitadel/internal/model" org_event "github.com/caos/zitadel/internal/org/repository/eventsourcing" @@ -184,27 +187,27 @@ func (repo *UserRepo) ExternalIDPsByIDPConfigIDAndResourceOwner(ctx context.Cont return model.ExternalIDPViewsToModel(externalIDPs), nil } -func (repo *UserRepo) GetMachineKey(ctx context.Context, userID, keyID string) (*usr_model.MachineKeyView, error) { - key, err := repo.View.MachineKeyByIDs(userID, keyID) +func (repo *UserRepo) GetMachineKey(ctx context.Context, userID, keyID string) (*key_model.AuthNKeyView, error) { + key, err := repo.View.AuthNKeyByIDs(userID, keyID) if err != nil { return nil, err } - return model.MachineKeyToModel(key), nil + return key_view_model.AuthNKeyToModel(key), nil } -func (repo *UserRepo) SearchMachineKeys(ctx context.Context, request *usr_model.MachineKeySearchRequest) (*usr_model.MachineKeySearchResponse, error) { +func (repo *UserRepo) SearchMachineKeys(ctx context.Context, request *key_model.AuthNKeySearchRequest) (*key_model.AuthNKeySearchResponse, error) { request.EnsureLimit(repo.SearchLimit) - sequence, seqErr := repo.View.GetLatestMachineKeySequence() - logging.Log("EVENT-Sk8fs").OnError(seqErr).Warn("could not read latest user sequence") - keys, count, err := repo.View.SearchMachineKeys(request) + sequence, seqErr := repo.View.GetLatestAuthNKeySequence() + logging.Log("EVENT-Sk8fs").OnError(seqErr).Warn("could not read latest authn key sequence") + keys, count, err := repo.View.SearchAuthNKeys(request) if err != nil { return nil, err } - result := &usr_model.MachineKeySearchResponse{ + result := &key_model.AuthNKeySearchResponse{ Offset: request.Offset, Limit: request.Limit, TotalResult: count, - Result: model.MachineKeysToModel(keys), + Result: key_view_model.AuthNKeysToModel(keys), } if seqErr == nil { result.Sequence = sequence.CurrentSequence diff --git a/internal/management/repository/eventsourcing/handler/application.go b/internal/management/repository/eventsourcing/handler/application.go index c18a05572..71e4c2af0 100644 --- a/internal/management/repository/eventsourcing/handler/application.go +++ b/internal/management/repository/eventsourcing/handler/application.go @@ -87,6 +87,8 @@ func (a *Application) Reduce(event *models.Event) (err error) { case es_model.ApplicationChanged, es_model.OIDCConfigAdded, es_model.OIDCConfigChanged, + es_model.APIConfigAdded, + es_model.APIConfigChanged, es_model.ApplicationDeactivated, es_model.ApplicationReactivated: err = app.SetData(event) diff --git a/internal/management/repository/eventsourcing/handler/authn_keys.go b/internal/management/repository/eventsourcing/handler/authn_keys.go new file mode 100644 index 000000000..000301003 --- /dev/null +++ b/internal/management/repository/eventsourcing/handler/authn_keys.go @@ -0,0 +1,120 @@ +package handler + +import ( + "time" + + "github.com/caos/logging" + + "github.com/caos/zitadel/internal/eventstore" + es_models "github.com/caos/zitadel/internal/eventstore/models" + "github.com/caos/zitadel/internal/eventstore/query" + "github.com/caos/zitadel/internal/eventstore/spooler" + key_model "github.com/caos/zitadel/internal/key/repository/view/model" + proj_model "github.com/caos/zitadel/internal/project/repository/eventsourcing/model" + user_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model" +) + +const ( + authnKeysTable = "management.authn_keys" +) + +type AuthNKeys struct { + handler + subscription *eventstore.Subscription +} + +func newAuthNKeys(handler handler) *AuthNKeys { + h := &AuthNKeys{ + handler: handler, + } + + h.subscribe() + + return h +} + +func (k *AuthNKeys) subscribe() { + k.subscription = k.es.Subscribe(k.AggregateTypes()...) + go func() { + for event := range k.subscription.Events { + query.ReduceEvent(k, event) + } + }() +} + +func (k *AuthNKeys) ViewModel() string { + return authnKeysTable +} + +func (_ *AuthNKeys) AggregateTypes() []es_models.AggregateType { + return []es_models.AggregateType{user_model.UserAggregate, proj_model.ProjectAggregate} +} + +func (k *AuthNKeys) CurrentSequence() (uint64, error) { + sequence, err := k.view.GetLatestAuthNKeySequence() + if err != nil { + return 0, err + } + return sequence.CurrentSequence, nil +} + +func (k *AuthNKeys) EventQuery() (*es_models.SearchQuery, error) { + sequence, err := k.view.GetLatestAuthNKeySequence() + if err != nil { + return nil, err + } + return es_models.NewSearchQuery(). + AggregateTypeFilter(k.AggregateTypes()...). + LatestSequenceFilter(sequence.CurrentSequence), nil +} + +func (k *AuthNKeys) Reduce(event *es_models.Event) (err error) { + switch event.AggregateType { + case user_model.UserAggregate, + proj_model.ProjectAggregate: + err = k.processAuthNKeys(event) + } + return err +} + +func (k *AuthNKeys) processAuthNKeys(event *es_models.Event) (err error) { + key := new(key_model.AuthNKeyView) + switch event.Type { + case user_model.MachineKeyAdded, + proj_model.ClientKeyAdded: + err = key.AppendEvent(event) + if key.ExpirationDate.Before(time.Now()) { + return k.view.ProcessedAuthNKeySequence(event) + } + case user_model.MachineKeyRemoved: + err = key.SetUserData(event) + if err != nil { + return err + } + return k.view.DeleteAuthNKey(key.ID, event) + case proj_model.ClientKeyRemoved: + err = key.SetClientData(event) + if err != nil { + return err + } + return k.view.DeleteAuthNKey(key.ID, event) + case user_model.UserRemoved, + proj_model.ApplicationRemoved: + return k.view.DeleteAuthNKeysByObjectID(event.AggregateID, event) + default: + return k.view.ProcessedAuthNKeySequence(event) + } + if err != nil { + return err + } + return k.view.PutAuthNKey(key, event) +} + +func (d *AuthNKeys) OnError(event *es_models.Event, err error) error { + logging.LogWithFields("SPOOL-S9fe", "id", event.AggregateID).WithError(err).Warn("something went wrong in machine key handler") + return spooler.HandleError(event, err, d.view.GetLatestAuthNKeyFailedEvent, d.view.ProcessedAuthNKeyFailedEvent, d.view.ProcessedAuthNKeySequence, d.errorCountUntilSkip) +} + +func (d *AuthNKeys) OnSuccess() error { + return spooler.HandleSuccess(d.view.UpdateAuthNKeySpoolerRunTimestamp) +} diff --git a/internal/management/repository/eventsourcing/handler/handler.go b/internal/management/repository/eventsourcing/handler/handler.go index adf3ec26f..10aa72925 100644 --- a/internal/management/repository/eventsourcing/handler/handler.go +++ b/internal/management/repository/eventsourcing/handler/handler.go @@ -75,7 +75,7 @@ func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, es handler{view, bulkLimit, configs.cycleDuration("UserMembership"), errorCount, es}, repos.OrgEvents, repos.ProjectEvents), - newMachineKeys( + newAuthNKeys( handler{view, bulkLimit, configs.cycleDuration("MachineKeys"), errorCount, es}), newIDPConfig( handler{view, bulkLimit, configs.cycleDuration("IDPConfig"), errorCount, es}), diff --git a/internal/management/repository/eventsourcing/handler/machine_keys.go b/internal/management/repository/eventsourcing/handler/machine_keys.go deleted file mode 100644 index cabe5f0cd..000000000 --- a/internal/management/repository/eventsourcing/handler/machine_keys.go +++ /dev/null @@ -1,110 +0,0 @@ -package handler - -import ( - "time" - - "github.com/caos/logging" - "github.com/caos/zitadel/internal/eventstore" - "github.com/caos/zitadel/internal/eventstore/models" - es_models "github.com/caos/zitadel/internal/eventstore/models" - "github.com/caos/zitadel/internal/eventstore/query" - "github.com/caos/zitadel/internal/eventstore/spooler" - "github.com/caos/zitadel/internal/user/repository/eventsourcing/model" - usr_model "github.com/caos/zitadel/internal/user/repository/view/model" -) - -const ( - machineKeysTable = "management.machine_keys" -) - -type MachineKeys struct { - handler - subscription *eventstore.Subscription -} - -func newMachineKeys(handler handler) *MachineKeys { - h := &MachineKeys{ - handler: handler, - } - - h.subscribe() - - return h -} - -func (m *MachineKeys) subscribe() { - m.subscription = m.es.Subscribe(m.AggregateTypes()...) - go func() { - for event := range m.subscription.Events { - query.ReduceEvent(m, event) - } - }() -} - -func (d *MachineKeys) ViewModel() string { - return machineKeysTable -} - -func (_ *MachineKeys) AggregateTypes() []es_models.AggregateType { - return []es_models.AggregateType{model.UserAggregate} -} - -func (k *MachineKeys) CurrentSequence() (uint64, error) { - sequence, err := k.view.GetLatestMachineKeySequence() - if err != nil { - return 0, err - } - return sequence.CurrentSequence, nil -} - -func (d *MachineKeys) EventQuery() (*models.SearchQuery, error) { - sequence, err := d.view.GetLatestMachineKeySequence() - if err != nil { - return nil, err - } - return es_models.NewSearchQuery(). - AggregateTypeFilter(d.AggregateTypes()...). - LatestSequenceFilter(sequence.CurrentSequence), nil -} - -func (d *MachineKeys) Reduce(event *models.Event) (err error) { - switch event.AggregateType { - case model.UserAggregate: - err = d.processMachineKeys(event) - } - return err -} - -func (d *MachineKeys) processMachineKeys(event *models.Event) (err error) { - key := new(usr_model.MachineKeyView) - switch event.Type { - case model.MachineKeyAdded: - err = key.AppendEvent(event) - if key.ExpirationDate.Before(time.Now()) { - return d.view.ProcessedMachineKeySequence(event) - } - case model.MachineKeyRemoved: - err = key.SetData(event) - if err != nil { - return err - } - return d.view.DeleteMachineKey(key.ID, event) - case model.UserRemoved: - return d.view.DeleteMachineKeysByUserID(event.AggregateID, event) - default: - return d.view.ProcessedMachineKeySequence(event) - } - if err != nil { - return err - } - return d.view.PutMachineKey(key, event) -} - -func (d *MachineKeys) OnError(event *models.Event, err error) error { - logging.LogWithFields("SPOOL-S9fe", "id", event.AggregateID).WithError(err).Warn("something went wrong in machine key handler") - return spooler.HandleError(event, err, d.view.GetLatestMachineKeyFailedEvent, d.view.ProcessedMachineKeyFailedEvent, d.view.ProcessedMachineKeySequence, d.errorCountUntilSkip) -} - -func (d *MachineKeys) OnSuccess() error { - return spooler.HandleSuccess(d.view.UpdateMachineKeySpoolerRunTimestamp) -} diff --git a/internal/management/repository/eventsourcing/view/authn_keys.go b/internal/management/repository/eventsourcing/view/authn_keys.go new file mode 100644 index 000000000..cc982dc4c --- /dev/null +++ b/internal/management/repository/eventsourcing/view/authn_keys.go @@ -0,0 +1,74 @@ +package view + +import ( + "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/eventstore/models" + key_model "github.com/caos/zitadel/internal/key/model" + "github.com/caos/zitadel/internal/key/repository/view" + "github.com/caos/zitadel/internal/key/repository/view/model" + "github.com/caos/zitadel/internal/view/repository" +) + +const ( + authNKeyTable = "management.authn_keys" +) + +func (v *View) AuthNKeyByIDs(objectID, keyID string) (*model.AuthNKeyView, error) { + return view.AuthNKeyByIDs(v.Db, authNKeyTable, objectID, keyID) +} + +func (v *View) AuthNKeysByObjectID(objectID string) ([]*model.AuthNKeyView, error) { + return view.AuthNKeysByObjectID(v.Db, authNKeyTable, objectID) +} + +func (v *View) AuthNKeyByID(keyID string) (*model.AuthNKeyView, error) { + return view.AuthNKeyByID(v.Db, authNKeyTable, keyID) +} + +func (v *View) SearchAuthNKeys(request *key_model.AuthNKeySearchRequest) ([]*model.AuthNKeyView, uint64, error) { + return view.SearchAuthNKeys(v.Db, authNKeyTable, request) +} + +func (v *View) PutAuthNKey(key *model.AuthNKeyView, event *models.Event) error { + err := view.PutAuthNKey(v.Db, authNKeyTable, key) + if err != nil { + return err + } + return v.ProcessedAuthNKeySequence(event) +} + +func (v *View) DeleteAuthNKey(keyID string, event *models.Event) error { + err := view.DeleteAuthNKey(v.Db, authNKeyTable, keyID) + if err != nil && !errors.IsNotFound(err) { + return err + } + return v.ProcessedAuthNKeySequence(event) +} + +func (v *View) DeleteAuthNKeysByObjectID(objectID string, event *models.Event) error { + err := view.DeleteAuthNKey(v.Db, authNKeyTable, objectID) + if err != nil && !errors.IsNotFound(err) { + return err + } + return v.ProcessedAuthNKeySequence(event) +} + +func (v *View) GetLatestAuthNKeySequence() (*repository.CurrentSequence, error) { + return v.latestSequence(authNKeyTable) +} + +func (v *View) ProcessedAuthNKeySequence(event *models.Event) error { + return v.saveCurrentSequence(authNKeyTable, event) +} + +func (v *View) UpdateAuthNKeySpoolerRunTimestamp() error { + return v.updateSpoolerRunSequence(authNKeyTable) +} + +func (v *View) GetLatestAuthNKeyFailedEvent(sequence uint64) (*repository.FailedEvent, error) { + return v.latestFailedEvent(authNKeyTable, sequence) +} + +func (v *View) ProcessedAuthNKeyFailedEvent(failedEvent *repository.FailedEvent) error { + return v.saveFailedEvent(failedEvent) +} diff --git a/internal/management/repository/eventsourcing/view/machine_keys.go b/internal/management/repository/eventsourcing/view/machine_keys.go deleted file mode 100644 index 075e15fe8..000000000 --- a/internal/management/repository/eventsourcing/view/machine_keys.go +++ /dev/null @@ -1,70 +0,0 @@ -package view - -import ( - "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/models" - usr_model "github.com/caos/zitadel/internal/user/model" - "github.com/caos/zitadel/internal/user/repository/view" - "github.com/caos/zitadel/internal/user/repository/view/model" - "github.com/caos/zitadel/internal/view/repository" -) - -const ( - machineKeyTable = "management.machine_keys" -) - -func (v *View) MachineKeyByIDs(userID, keyID string) (*model.MachineKeyView, error) { - return view.MachineKeyByIDs(v.Db, machineKeyTable, userID, keyID) -} - -func (v *View) MachineKeysByUserID(userID string) ([]*model.MachineKeyView, error) { - return view.MachineKeysByUserID(v.Db, machineKeyTable, userID) -} - -func (v *View) SearchMachineKeys(request *usr_model.MachineKeySearchRequest) ([]*model.MachineKeyView, uint64, error) { - return view.SearchMachineKeys(v.Db, machineKeyTable, request) -} - -func (v *View) PutMachineKey(org *model.MachineKeyView, event *models.Event) error { - err := view.PutMachineKey(v.Db, machineKeyTable, org) - if err != nil { - return err - } - return v.ProcessedMachineKeySequence(event) -} - -func (v *View) DeleteMachineKey(keyID string, event *models.Event) error { - err := view.DeleteMachineKey(v.Db, machineKeyTable, keyID) - if err != nil && !errors.IsNotFound(err) { - return err - } - return v.ProcessedMachineKeySequence(event) -} - -func (v *View) DeleteMachineKeysByUserID(userID string, event *models.Event) error { - err := view.DeleteMachineKey(v.Db, machineKeyTable, userID) - if err != nil && !errors.IsNotFound(err) { - return err - } - return v.ProcessedMachineKeySequence(event) -} - -func (v *View) GetLatestMachineKeySequence() (*repository.CurrentSequence, error) { - return v.latestSequence(machineKeyTable) -} - -func (v *View) ProcessedMachineKeySequence(event *models.Event) error { - return v.saveCurrentSequence(machineKeyTable, event) -} - -func (v *View) UpdateMachineKeySpoolerRunTimestamp() error { - return v.updateSpoolerRunSequence(machineKeyTable) -} - -func (v *View) GetLatestMachineKeyFailedEvent(sequence uint64) (*repository.FailedEvent, error) { - return v.latestFailedEvent(machineKeyTable, sequence) -} - -func (v *View) ProcessedMachineKeyFailedEvent(failedEvent *repository.FailedEvent) error { - return v.saveFailedEvent(failedEvent) -} diff --git a/internal/management/repository/project.go b/internal/management/repository/project.go index 8960006f2..da72adeb7 100644 --- a/internal/management/repository/project.go +++ b/internal/management/repository/project.go @@ -3,6 +3,7 @@ package repository import ( "context" + key_model "github.com/caos/zitadel/internal/key/model" "github.com/caos/zitadel/internal/project/model" ) @@ -23,9 +24,16 @@ type ProjectRepository interface { ProjectChanges(ctx context.Context, id string, lastSequence uint64, limit uint64, sortAscending bool) (*model.ProjectChanges, error) ApplicationByID(ctx context.Context, projectID, appID string) (*model.ApplicationView, error) + AddApplication(ctx context.Context, app *model.Application) (*model.Application, error) + ChangeAPIConfig(ctx context.Context, config *model.APIConfig) (*model.APIConfig, error) ChangeOIDConfigSecret(ctx context.Context, projectID, appID string) (*model.OIDCConfig, error) + ChangeAPIConfigSecret(ctx context.Context, projectID, appID string) (*model.APIConfig, error) SearchApplications(ctx context.Context, request *model.ApplicationSearchRequest) (*model.ApplicationSearchResponse, error) ApplicationChanges(ctx context.Context, id string, secId string, lastSequence uint64, limit uint64, sortAscending bool) (*model.ApplicationChanges, error) + SearchClientKeys(ctx context.Context, request *key_model.AuthNKeySearchRequest) (*key_model.AuthNKeySearchResponse, error) + GetClientKey(ctx context.Context, projectID, applicationID, keyID string) (*key_model.AuthNKeyView, error) + AddClientKey(ctx context.Context, key *model.ClientKey) (*model.ClientKey, error) + RemoveClientKey(ctx context.Context, projectID, applicationID, keyID string) error ProjectGrantByID(ctx context.Context, grantID string) (*model.ProjectGrantView, error) SearchProjectGrantMembers(ctx context.Context, request *model.ProjectGrantMemberSearchRequest) (*model.ProjectGrantMemberSearchResponse, error) diff --git a/internal/management/repository/user.go b/internal/management/repository/user.go index 976e0097a..0eafac5ac 100644 --- a/internal/management/repository/user.go +++ b/internal/management/repository/user.go @@ -3,6 +3,7 @@ package repository import ( "context" + key_model "github.com/caos/zitadel/internal/key/model" "github.com/caos/zitadel/internal/user/model" ) @@ -26,8 +27,8 @@ type UserRepository interface { ExternalIDPsByIDPConfigID(ctx context.Context, idpConfigID string) ([]*model.ExternalIDPView, error) ExternalIDPsByIDPConfigIDAndResourceOwner(ctx context.Context, idpConfigID, resourceOwner string) ([]*model.ExternalIDPView, error) - SearchMachineKeys(ctx context.Context, request *model.MachineKeySearchRequest) (*model.MachineKeySearchResponse, error) - GetMachineKey(ctx context.Context, userID, keyID string) (*model.MachineKeyView, error) + SearchMachineKeys(ctx context.Context, request *key_model.AuthNKeySearchRequest) (*key_model.AuthNKeySearchResponse, error) + GetMachineKey(ctx context.Context, userID, keyID string) (*key_model.AuthNKeyView, error) EmailByID(ctx context.Context, userID string) (*model.Email, error) diff --git a/internal/project/model/api_config.go b/internal/project/model/api_config.go new file mode 100644 index 000000000..4a3a31202 --- /dev/null +++ b/internal/project/model/api_config.go @@ -0,0 +1,62 @@ +package model + +import ( + "fmt" + "strings" + + "github.com/caos/logging" + + "github.com/caos/zitadel/internal/crypto" + "github.com/caos/zitadel/internal/errors" + es_models "github.com/caos/zitadel/internal/eventstore/models" + "github.com/caos/zitadel/internal/id" +) + +type APIConfig struct { + es_models.ObjectRoot + AppID string + ClientID string + ClientSecret *crypto.CryptoValue + ClientSecretString string + AuthMethodType APIAuthMethodType + ClientKeys []*ClientKey +} + +type APIAuthMethodType int32 + +const ( + APIAuthMethodTypeBasic APIAuthMethodType = iota + APIAuthMethodTypePrivateKeyJWT +) + +func (c *APIConfig) IsValid() bool { + return true +} + +//ClientID random_number@projectname (eg. 495894098234@zitadel) +func (c *APIConfig) GenerateNewClientID(idGenerator id.Generator, project *Project) error { + rndID, err := idGenerator.Next() + if err != nil { + return err + } + + c.ClientID = fmt.Sprintf("%v@%v", rndID, strings.ReplaceAll(strings.ToLower(project.Name), " ", "_")) + return nil +} + +func (c *APIConfig) GenerateClientSecretIfNeeded(generator crypto.Generator) (string, error) { + if c.AuthMethodType == APIAuthMethodTypeBasic { + return c.GenerateNewClientSecret(generator) + } + return "", nil +} + +func (c *APIConfig) GenerateNewClientSecret(generator crypto.Generator) (string, error) { + cryptoValue, stringSecret, err := crypto.NewCode(generator) + if err != nil { + logging.Log("MODEL-ADvd2").OnError(err).Error("unable to create client secret") + return "", errors.ThrowInternal(err, "MODEL-dsvr43", "Errors.Project.CouldNotGenerateClientSecret") + } + c.ClientSecret = cryptoValue + return stringSecret, nil +} diff --git a/internal/project/model/application.go b/internal/project/model/application.go index d3dd02881..eba494caa 100644 --- a/internal/project/model/application.go +++ b/internal/project/model/application.go @@ -1,8 +1,9 @@ package model import ( - es_models "github.com/caos/zitadel/internal/eventstore/models" "github.com/golang/protobuf/ptypes/timestamp" + + es_models "github.com/caos/zitadel/internal/eventstore/models" ) type Application struct { @@ -13,6 +14,7 @@ type Application struct { Name string Type AppType OIDCConfig *OIDCConfig + APIConfig *APIConfig } type ApplicationChanges struct { Changes []*ApplicationChange @@ -42,6 +44,7 @@ const ( AppTypeUnspecified AppType = iota AppTypeOIDC AppTypeSAML + AppTypeAPI ) func NewApplication(projectID, appID string) *Application { @@ -58,5 +61,20 @@ func (a *Application) IsValid(includeConfig bool) bool { if a.Type == AppTypeOIDC && !a.OIDCConfig.IsValid() { return false } + if a.Type == AppTypeAPI && !a.APIConfig.IsValid() { + return false + } return true } + +func (a *Application) GetKey(keyID string) (int, *ClientKey) { + if a.OIDCConfig == nil { + return -1, nil + } + for i, k := range a.OIDCConfig.ClientKeys { + if k.KeyID == keyID { + return i, k + } + } + return -1, nil +} diff --git a/internal/project/model/oidc_config.go b/internal/project/model/oidc_config.go index 8c04b9fba..647c8ac0a 100644 --- a/internal/project/model/oidc_config.go +++ b/internal/project/model/oidc_config.go @@ -11,6 +11,7 @@ import ( "github.com/caos/zitadel/internal/errors" es_models "github.com/caos/zitadel/internal/eventstore/models" "github.com/caos/zitadel/internal/id" + key_model "github.com/caos/zitadel/internal/key/model" ) const ( @@ -40,6 +41,7 @@ type OIDCConfig struct { IDTokenRoleAssertion bool IDTokenUserinfoAssertion bool ClockSkew time.Duration + ClientKeys []*ClientKey } type OIDCVersion int32 @@ -78,6 +80,7 @@ const ( OIDCAuthMethodTypeBasic OIDCAuthMethodType = iota OIDCAuthMethodTypePost OIDCAuthMethodTypeNone + OIDCAuthMethodTypePrivateKeyJWT ) type Compliance struct { @@ -92,6 +95,27 @@ const ( OIDCTokenTypeJWT ) +type ClientKey struct { + es_models.ObjectRoot + + ApplicationID string + ClientID string + KeyID string + Type key_model.AuthNKeyType + ExpirationDate time.Time + PrivateKey []byte +} + +type Token struct { + es_models.ObjectRoot + + TokenID string + ClientID string + Audience []string + Expiration time.Time + Scopes []string +} + func (c *OIDCConfig) IsValid() bool { grantTypes := c.getRequiredGrantTypes() for _, grantType := range grantTypes { @@ -115,10 +139,10 @@ func (c *OIDCConfig) GenerateNewClientID(idGenerator id.Generator, project *Proj } func (c *OIDCConfig) GenerateClientSecretIfNeeded(generator crypto.Generator) (string, error) { - if c.AuthMethodType == OIDCAuthMethodTypeNone { - return "", nil + if c.AuthMethodType == OIDCAuthMethodTypeBasic || c.AuthMethodType == OIDCAuthMethodTypePost { + return c.GenerateNewClientSecret(generator) } - return c.GenerateNewClientSecret(generator) + return "", nil } func (c *OIDCConfig) GenerateNewClientSecret(generator crypto.Generator) (string, error) { diff --git a/internal/project/repository/eventsourcing/eventstore.go b/internal/project/repository/eventsourcing/eventstore.go index 1b53c4e3e..f5e211945 100644 --- a/internal/project/repository/eventsourcing/eventstore.go +++ b/internal/project/repository/eventsourcing/eventstore.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "strings" + "time" "github.com/caos/logging" "github.com/golang/protobuf/ptypes" @@ -18,6 +19,7 @@ import ( es_models "github.com/caos/zitadel/internal/eventstore/models" es_sdk "github.com/caos/zitadel/internal/eventstore/sdk" "github.com/caos/zitadel/internal/id" + key_model "github.com/caos/zitadel/internal/key/model" proj_model "github.com/caos/zitadel/internal/project/model" "github.com/caos/zitadel/internal/project/repository/eventsourcing/model" "github.com/caos/zitadel/internal/telemetry/tracing" @@ -30,10 +32,11 @@ const ( type ProjectEventstore struct { es_int.Eventstore - projectCache *ProjectCache - passwordAlg crypto.HashAlgorithm - pwGenerator crypto.Generator - idGenerator id.Generator + projectCache *ProjectCache + passwordAlg crypto.HashAlgorithm + pwGenerator crypto.Generator + idGenerator id.Generator + ClientKeySize int } type ProjectConfig struct { @@ -49,11 +52,12 @@ func StartProject(conf ProjectConfig, systemDefaults sd.SystemDefaults) (*Projec passwordAlg := crypto.NewBCrypt(systemDefaults.SecretGenerators.PasswordSaltCost) pwGenerator := crypto.NewHashGenerator(systemDefaults.SecretGenerators.ClientSecretGenerator, passwordAlg) return &ProjectEventstore{ - Eventstore: conf.Eventstore, - projectCache: projectCache, - passwordAlg: passwordAlg, - pwGenerator: pwGenerator, - idGenerator: id.SonyFlakeGenerator, + Eventstore: conf.Eventstore, + projectCache: projectCache, + passwordAlg: passwordAlg, + pwGenerator: pwGenerator, + idGenerator: id.SonyFlakeGenerator, + ClientKeySize: int(systemDefaults.SecretGenerators.ClientKeySize), }, nil } @@ -513,15 +517,14 @@ func (es *ProjectEventstore) AddApplication(ctx context.Context, app *proj_model if err != nil { return nil, err } - id, err := es.idGenerator.Next() + app.AppID, err = es.idGenerator.Next() if err != nil { return nil, err } - app.AppID = id var stringPw string if app.OIDCConfig != nil { - app.OIDCConfig.AppID = id + app.OIDCConfig.AppID = app.AppID err := app.OIDCConfig.GenerateNewClientID(es.idGenerator, existingProject) if err != nil { return nil, err @@ -531,6 +534,17 @@ func (es *ProjectEventstore) AddApplication(ctx context.Context, app *proj_model return nil, err } } + if app.APIConfig != nil { + app.APIConfig.AppID = app.AppID + err := app.APIConfig.GenerateNewClientID(es.idGenerator, existingProject) + if err != nil { + return nil, err + } + stringPw, err = app.APIConfig.GenerateClientSecretIfNeeded(es.pwGenerator) + if err != nil { + return nil, err + } + } repoProject := model.ProjectFromModel(existingProject) repoApp := model.AppFromModel(app) @@ -542,8 +556,13 @@ func (es *ProjectEventstore) AddApplication(ctx context.Context, app *proj_model es.projectCache.cacheProject(repoProject) if _, a := model.GetApplication(repoProject.Applications, app.AppID); a != nil { converted := model.AppToModel(a) - converted.OIDCConfig.ClientSecretString = stringPw - converted.OIDCConfig.FillCompliance() + if converted.OIDCConfig != nil { + converted.OIDCConfig.ClientSecretString = stringPw + converted.OIDCConfig.FillCompliance() + } + if converted.APIConfig != nil { + converted.APIConfig.ClientSecretString = stringPw + } return converted, nil } return nil, caos_errs.ThrowInternal(nil, "EVENT-GvPct", "Errors.Internal") @@ -748,6 +767,36 @@ func (es *ProjectEventstore) ChangeOIDCConfig(ctx context.Context, config *proj_ return nil, caos_errs.ThrowInternal(nil, "EVENT-dk87s", "Errors.Internal") } +func (es *ProjectEventstore) ChangeAPIConfig(ctx context.Context, config *proj_model.APIConfig) (*proj_model.APIConfig, error) { + if config == nil || !config.IsValid() { + return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-SDg54", "Errors.Project.APIConfigInvalid") + } + existingProject, err := es.ProjectByID(ctx, config.AggregateID) + if err != nil { + return nil, err + } + var app *proj_model.Application + if _, app = existingProject.GetApp(config.AppID); app == nil { + return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-Rgu63", "Errors.Project.AppNotExisting") + } + if app.Type != proj_model.AppTypeAPI { + return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-RHj63", "Errors.Project.AppIsNotAPI") + } + repoProject := model.ProjectFromModel(existingProject) + repoConfig := model.APIConfigFromModel(config) + + projectAggregate := APIConfigChangedAggregate(es.Eventstore.AggregateCreator(), repoProject, repoConfig) + err = es_sdk.Push(ctx, es.PushAggregates, repoProject.AppendEvents, projectAggregate) + if err != nil { + return nil, err + } + es.projectCache.cacheProject(repoProject) + if _, a := model.GetApplication(repoProject.Applications, app.AppID); a != nil { + return model.APIConfigToModel(a.APIConfig), nil + } + return nil, caos_errs.ThrowInternal(nil, "EVENT-aebn5", "Errors.Internal") +} + func (es *ProjectEventstore) ChangeOIDCConfigSecret(ctx context.Context, projectID, appID string) (*proj_model.OIDCConfig, error) { if appID == "" { return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-7ue34", "Errors.Project.App.OIDCConfigInvalid") @@ -763,8 +812,8 @@ func (es *ProjectEventstore) ChangeOIDCConfigSecret(ctx context.Context, project if app.Type != proj_model.AppTypeOIDC { return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-dile4", "Errors.Project.App.IsNotOIDC") } - if app.OIDCConfig.AuthMethodType == proj_model.OIDCAuthMethodTypeNone { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-GDrg2", "Errors.Project.OIDCAuthMethodNoneSecret") + if app.OIDCConfig.AuthMethodType == proj_model.OIDCAuthMethodTypeNone || app.OIDCConfig.AuthMethodType == proj_model.OIDCAuthMethodTypePrivateKeyJWT { + return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-GDrg2", "Errors.Project.OIDCAuthMethodNoSecret") } repoProject := model.ProjectFromModel(existingProject) @@ -789,6 +838,47 @@ func (es *ProjectEventstore) ChangeOIDCConfigSecret(ctx context.Context, project return nil, caos_errs.ThrowInternal(nil, "EVENT-dk87s", "Errors.Internal") } +func (es *ProjectEventstore) ChangeAPIConfigSecret(ctx context.Context, projectID, appID string) (*proj_model.APIConfig, error) { + if appID == "" { + return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-sdfb3", "Errors.Project.APIConfigInvalid") + } + existingProject, err := es.ProjectByID(ctx, projectID) + if err != nil { + return nil, err + } + var app *proj_model.Application + if _, app = existingProject.GetApp(appID); app == nil { + return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-ADbg3", "Errors.Project.AppNotExisting") + } + if app.Type != proj_model.AppTypeAPI { + return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-Ntwqw", "Errors.Project.AppIsNotAPI") + } + if app.APIConfig.AuthMethodType != proj_model.APIAuthMethodTypeBasic { + return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-HW4tw", "Errors.Project.APIAuthMethodNoSecret") + } + repoProject := model.ProjectFromModel(existingProject) + + stringPw, err := app.APIConfig.GenerateNewClientSecret(es.pwGenerator) + if err != nil { + return nil, err + } + + projectAggregate := APIConfigSecretChangedAggregate(es.Eventstore.AggregateCreator(), repoProject, appID, app.APIConfig.ClientSecret) + err = es_sdk.Push(ctx, es.PushAggregates, repoProject.AppendEvents, projectAggregate) + if err != nil { + return nil, err + } + es.projectCache.cacheProject(repoProject) + + if _, a := model.GetApplication(repoProject.Applications, app.AppID); a != nil { + config := model.APIConfigToModel(a.APIConfig) + config.ClientSecretString = stringPw + return config, nil + } + + return nil, caos_errs.ThrowInternal(nil, "EVENT-HBfju", "Errors.Internal") +} + func (es *ProjectEventstore) VerifyOIDCClientSecret(ctx context.Context, projectID, appID string, secret string) (err error) { ctx, span := tracing.NewSpan(ctx) defer func() { span.EndWithError(err) }() @@ -831,6 +921,81 @@ func (es *ProjectEventstore) setOIDCClientSecretCheckResult(ctx context.Context, return nil } +func (es *ProjectEventstore) AddClientKey(ctx context.Context, key *proj_model.ClientKey) (*proj_model.ClientKey, error) { + existingProject, err := es.ProjectByID(ctx, key.AggregateID) + if err != nil { + return nil, err + } + var app *proj_model.Application + if _, app = existingProject.GetApp(key.ApplicationID); app == nil { + return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-Dbf32", "Errors.Project.AppNoExisting") + } + if (app.OIDCConfig == nil || app.OIDCConfig != nil && app.OIDCConfig.AuthMethodType != proj_model.OIDCAuthMethodTypePrivateKeyJWT) && + (app.APIConfig == nil || app.APIConfig != nil && app.APIConfig.AuthMethodType != proj_model.APIAuthMethodTypePrivateKeyJWT) { + return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-Dff54", "Errors.Project.AuthMethodNoPrivateKeyJWT") + } + if app.OIDCConfig != nil { + key.ClientID = app.OIDCConfig.ClientID + } + if app.APIConfig != nil { + key.ClientID = app.APIConfig.ClientID + } + key.KeyID, err = es.idGenerator.Next() + if err != nil { + return nil, err + } + if key.ExpirationDate.IsZero() { + key.ExpirationDate, err = key_model.DefaultExpiration() + if err != nil { + logging.Log("EVENT-Adgf2").WithError(err).Warn("unable to set default date") + return nil, errors.ThrowInternal(err, "EVENT-j68fg", "Errors.Internal") + } + } + if key.ExpirationDate.Before(time.Now()) { + return nil, errors.ThrowInvalidArgument(nil, "EVENT-C6YV5", "Errors.MachineKey.ExpireBeforeNow") + } + + repoProject := model.ProjectFromModel(existingProject) + repoKey := model.ClientKeyFromModel(key) + err = repoKey.GenerateClientKeyPair(es.ClientKeySize) + if err != nil { + return nil, err + } + agg := OIDCApplicationKeyAddedAggregate(es.AggregateCreator(), repoProject, repoKey) + err = es_sdk.Push(ctx, es.PushAggregates, repoProject.AppendEvents, agg) + if err != nil { + return nil, err + } + es.projectCache.cacheProject(repoProject) + + return model.ClientKeyToModel(repoKey), nil +} + +func (es *ProjectEventstore) RemoveApplicationKey(ctx context.Context, projectID, applicationID, keyID string) error { + existingProject, err := es.ProjectByID(ctx, projectID) + if err != nil { + return err + } + var app *proj_model.Application + if _, app = existingProject.GetApp(applicationID); app == nil { + return caos_errs.ThrowPreconditionFailed(nil, "EVENT-ADfzz", "Errors.Project.AppNotExisting") + } + if app.Type != proj_model.AppTypeOIDC { + return caos_errs.ThrowPreconditionFailed(nil, "EVENT-ADffh", "Errors.Project.AppIsNotOIDC") + } + if _, key := app.GetKey(keyID); key == nil { + return caos_errs.ThrowPreconditionFailed(nil, "EVENT-D2Sff", "Errors.Project.AppKeyNotExisting") + } + repoProject := model.ProjectFromModel(existingProject) + agg := OIDCApplicationKeyRemovedAggregate(es.AggregateCreator(), repoProject, keyID) + err = es_sdk.Push(ctx, es.PushAggregates, repoProject.AppendEvents, agg) + if err != nil { + return err + } + es.projectCache.cacheProject(repoProject) + return nil +} + func (es *ProjectEventstore) ProjectGrantByIDs(ctx context.Context, projectID, grantID string) (*proj_model.ProjectGrant, error) { if grantID == "" { return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-e8die", "Errors.Project.IDMissing") diff --git a/internal/project/repository/eventsourcing/model/api_config.go b/internal/project/repository/eventsourcing/model/api_config.go new file mode 100644 index 000000000..493b817c1 --- /dev/null +++ b/internal/project/repository/eventsourcing/model/api_config.go @@ -0,0 +1,87 @@ +package model + +import ( + "encoding/json" + + "github.com/caos/logging" + + "github.com/caos/zitadel/internal/crypto" + es_models "github.com/caos/zitadel/internal/eventstore/models" + "github.com/caos/zitadel/internal/project/model" +) + +type APIConfig struct { + es_models.ObjectRoot + AppID string `json:"appId"` + ClientID string `json:"clientId,omitempty"` + ClientSecret *crypto.CryptoValue `json:"clientSecret,omitempty"` + AuthMethodType int32 `json:"authMethodType,omitempty"` + ClientKeys []*ClientKey `json:"-"` +} + +func (c *APIConfig) Changes(changed *APIConfig) map[string]interface{} { + changes := make(map[string]interface{}, 1) + changes["appId"] = c.AppID + if c.AuthMethodType != changed.AuthMethodType { + changes["authMethodType"] = changed.AuthMethodType + } + return changes +} + +func APIConfigFromModel(config *model.APIConfig) *APIConfig { + return &APIConfig{ + ObjectRoot: config.ObjectRoot, + AppID: config.AppID, + ClientID: config.ClientID, + ClientSecret: config.ClientSecret, + AuthMethodType: int32(config.AuthMethodType), + } +} + +func APIConfigToModel(config *APIConfig) *model.APIConfig { + oidcConfig := &model.APIConfig{ + ObjectRoot: config.ObjectRoot, + AppID: config.AppID, + ClientID: config.ClientID, + ClientSecret: config.ClientSecret, + AuthMethodType: model.APIAuthMethodType(config.AuthMethodType), + ClientKeys: ClientKeysToModel(config.ClientKeys), + } + return oidcConfig +} + +func (p *Project) appendAddAPIConfigEvent(event *es_models.Event) error { + config := new(APIConfig) + err := config.setData(event) + if err != nil { + return err + } + config.ObjectRoot.CreationDate = event.CreationDate + if i, a := GetApplication(p.Applications, config.AppID); a != nil { + p.Applications[i].Type = int32(model.AppTypeAPI) + p.Applications[i].APIConfig = config + } + return nil +} + +func (p *Project) appendChangeAPIConfigEvent(event *es_models.Event) error { + config := new(APIConfig) + err := config.setData(event) + if err != nil { + return err + } + + if i, a := GetApplication(p.Applications, config.AppID); a != nil { + return p.Applications[i].APIConfig.setData(event) + } + return nil +} + +func (o *APIConfig) setData(event *es_models.Event) error { + o.ObjectRoot.AppendEvent(event) + if err := json.Unmarshal(event.Data, o); err != nil { + logging.Log("EVEN-d8e3s").WithError(err).Error("could not unmarshal event data") + return err + } + return nil +} diff --git a/internal/project/repository/eventsourcing/model/application.go b/internal/project/repository/eventsourcing/model/application.go index 72da70624..a08228c5d 100644 --- a/internal/project/repository/eventsourcing/model/application.go +++ b/internal/project/repository/eventsourcing/model/application.go @@ -2,7 +2,9 @@ package model import ( "encoding/json" + "github.com/caos/logging" + es_models "github.com/caos/zitadel/internal/eventstore/models" "github.com/caos/zitadel/internal/project/model" ) @@ -14,6 +16,7 @@ type Application struct { Name string `json:"name,omitempty"` Type int32 `json:"appType,omitempty"` OIDCConfig *OIDCConfig `json:"-"` + APIConfig *APIConfig `json:"-"` } type ApplicationID struct { @@ -66,6 +69,9 @@ func AppFromModel(app *model.Application) *Application { if app.OIDCConfig != nil { converted.OIDCConfig = OIDCConfigFromModel(app.OIDCConfig) } + if app.APIConfig != nil { + converted.APIConfig = APIConfigFromModel(app.APIConfig) + } return converted } @@ -80,6 +86,9 @@ func AppToModel(app *Application) *model.Application { if app.OIDCConfig != nil { converted.OIDCConfig = OIDCConfigToModel(app.OIDCConfig) } + if app.APIConfig != nil { + converted.APIConfig = APIConfigToModel(app.APIConfig) + } return converted } @@ -101,7 +110,7 @@ func (p *Project) appendChangeAppEvent(event *es_models.Event) error { return err } if i, a := GetApplication(p.Applications, app.AppID); a != nil { - p.Applications[i].setData(event) + return p.Applications[i].setData(event) } return nil } diff --git a/internal/project/repository/eventsourcing/model/oidc_config.go b/internal/project/repository/eventsourcing/model/oidc_config.go index c48974293..635d78d2f 100644 --- a/internal/project/repository/eventsourcing/model/oidc_config.go +++ b/internal/project/repository/eventsourcing/model/oidc_config.go @@ -8,7 +8,9 @@ import ( "github.com/caos/logging" "github.com/caos/zitadel/internal/crypto" + "github.com/caos/zitadel/internal/errors" es_models "github.com/caos/zitadel/internal/eventstore/models" + key_model "github.com/caos/zitadel/internal/key/model" "github.com/caos/zitadel/internal/project/model" ) @@ -30,6 +32,7 @@ type OIDCConfig struct { IDTokenRoleAssertion bool `json:"idTokenRoleAssertion,omitempty"` IDTokenUserinfoAssertion bool `json:"idTokenUserinfoAssertion,omitempty"` ClockSkew time.Duration `json:"clockSkew,omitempty"` + ClientKeys []*ClientKey `json:"-"` } func (c *OIDCConfig) Changes(changed *OIDCConfig) map[string]interface{} { @@ -134,6 +137,7 @@ func OIDCConfigToModel(config *OIDCConfig) *model.OIDCConfig { IDTokenRoleAssertion: config.IDTokenRoleAssertion, IDTokenUserinfoAssertion: config.IDTokenUserinfoAssertion, ClockSkew: config.ClockSkew, + ClientKeys: ClientKeysToModel(config.ClientKeys), } oidcConfig.FillCompliance() return oidcConfig @@ -161,7 +165,50 @@ func (p *Project) appendChangeOIDCConfigEvent(event *es_models.Event) error { } if i, a := GetApplication(p.Applications, config.AppID); a != nil { - p.Applications[i].OIDCConfig.setData(event) + return p.Applications[i].OIDCConfig.setData(event) + } + return nil +} + +func (p *Project) appendAddClientKeyEvent(event *es_models.Event) error { + key := new(ClientKey) + err := key.SetData(event) + if err != nil { + return err + } + + if i, a := GetApplication(p.Applications, key.ApplicationID); a != nil { + if a.OIDCConfig != nil { + p.Applications[i].OIDCConfig.ClientKeys = append(p.Applications[i].OIDCConfig.ClientKeys, key) + } + if a.APIConfig != nil { + p.Applications[i].APIConfig.ClientKeys = append(p.Applications[i].APIConfig.ClientKeys, key) + } + } + return nil +} + +func (p *Project) appendRemoveClientKeyEvent(event *es_models.Event) error { + key := new(ClientKey) + err := key.SetData(event) + if err != nil { + return err + } + if i, a := GetApplication(p.Applications, key.ApplicationID); a != nil { + if a.OIDCConfig != nil { + if j, k := GetClientKey(p.Applications[i].OIDCConfig.ClientKeys, key.KeyID); k != nil { + p.Applications[i].OIDCConfig.ClientKeys[j] = p.Applications[i].OIDCConfig.ClientKeys[len(p.Applications[i].OIDCConfig.ClientKeys)-1] + p.Applications[i].OIDCConfig.ClientKeys[len(p.Applications[i].OIDCConfig.ClientKeys)-1] = nil + p.Applications[i].OIDCConfig.ClientKeys = p.Applications[i].OIDCConfig.ClientKeys[:len(p.Applications[i].OIDCConfig.ClientKeys)-1] + } + } + if a.APIConfig != nil { + if j, k := GetClientKey(p.Applications[i].APIConfig.ClientKeys, key.KeyID); k != nil { + p.Applications[i].APIConfig.ClientKeys[j] = p.Applications[i].APIConfig.ClientKeys[len(p.Applications[i].APIConfig.ClientKeys)-1] + p.Applications[i].APIConfig.ClientKeys[len(p.Applications[i].APIConfig.ClientKeys)-1] = nil + p.Applications[i].APIConfig.ClientKeys = p.Applications[i].APIConfig.ClientKeys[:len(p.Applications[i].APIConfig.ClientKeys)-1] + } + } } return nil } @@ -174,3 +221,100 @@ func (o *OIDCConfig) setData(event *es_models.Event) error { } return nil } + +func GetClientKey(keys []*ClientKey, id string) (int, *ClientKey) { + for i, k := range keys { + if k.KeyID == id { + return i, k + } + } + return -1, nil +} + +type ClientKey struct { + es_models.ObjectRoot `json:"-"` + ApplicationID string `json:"applicationId,omitempty"` + ClientID string `json:"clientId,omitempty"` + KeyID string `json:"keyId,omitempty"` + Type int32 `json:"type,omitempty"` + ExpirationDate time.Time `json:"expirationDate,omitempty"` + PublicKey []byte `json:"publicKey,omitempty"` + privateKey []byte +} + +func (key *ClientKey) SetData(event *es_models.Event) error { + key.ObjectRoot.AppendEvent(event) + if err := json.Unmarshal(event.Data, key); err != nil { + logging.Log("EVEN-SADdg").WithError(err).Error("could not unmarshal event data") + return err + } + return nil +} + +func (key *ClientKey) AppendEvents(events ...*es_models.Event) error { + for _, event := range events { + err := key.AppendEvent(event) + if err != nil { + return err + } + } + return nil +} + +func (key *ClientKey) AppendEvent(event *es_models.Event) (err error) { + key.ObjectRoot.AppendEvent(event) + switch event.Type { + case ClientKeyAdded: + err = json.Unmarshal(event.Data, key) + if err != nil { + return errors.ThrowInternal(err, "MODEL-Fetg3", "Errors.Internal") + } + case ClientKeyRemoved: + key.ExpirationDate = event.CreationDate + } + return err +} + +func ClientKeyFromModel(key *model.ClientKey) *ClientKey { + return &ClientKey{ + ObjectRoot: key.ObjectRoot, + ExpirationDate: key.ExpirationDate, + ApplicationID: key.ApplicationID, + ClientID: key.ClientID, + KeyID: key.KeyID, + Type: int32(key.Type), + } +} + +func ClientKeysToModel(keys []*ClientKey) []*model.ClientKey { + clientKeys := make([]*model.ClientKey, len(keys)) + for i, key := range keys { + clientKeys[i] = ClientKeyToModel(key) + } + return clientKeys +} + +func ClientKeyToModel(key *ClientKey) *model.ClientKey { + return &model.ClientKey{ + ObjectRoot: key.ObjectRoot, + ExpirationDate: key.ExpirationDate, + ApplicationID: key.ApplicationID, + ClientID: key.ClientID, + KeyID: key.KeyID, + PrivateKey: key.privateKey, + Type: key_model.AuthNKeyType(key.Type), + } +} + +func (key *ClientKey) GenerateClientKeyPair(keySize int) error { + privateKey, publicKey, err := crypto.GenerateKeyPair(keySize) + if err != nil { + return err + } + key.PublicKey, err = crypto.PublicKeyToBytes(publicKey) + if err != nil { + return err + } + key.privateKey = crypto.PrivateKeyToBytes(privateKey) + return nil +} diff --git a/internal/project/repository/eventsourcing/model/project.go b/internal/project/repository/eventsourcing/model/project.go index c0f8d8e35..bdf133c30 100644 --- a/internal/project/repository/eventsourcing/model/project.go +++ b/internal/project/repository/eventsourcing/model/project.go @@ -139,6 +139,14 @@ func (p *Project) AppendEvent(event *es_models.Event) error { return p.appendAddOIDCConfigEvent(event) case OIDCConfigChanged, OIDCConfigSecretChanged: return p.appendChangeOIDCConfigEvent(event) + case APIConfigAdded: + return p.appendAddAPIConfigEvent(event) + case APIConfigChanged, APIConfigSecretChanged: + return p.appendChangeAPIConfigEvent(event) + case ClientKeyAdded: + return p.appendAddClientKeyEvent(event) + case ClientKeyRemoved: + return p.appendRemoveClientKeyEvent(event) case ProjectGrantAdded: return p.appendAddGrantEvent(event) case ProjectGrantChanged, ProjectGrantCascadeChanged: diff --git a/internal/project/repository/eventsourcing/model/types.go b/internal/project/repository/eventsourcing/model/types.go index 2bf2f3845..581627142 100644 --- a/internal/project/repository/eventsourcing/model/types.go +++ b/internal/project/repository/eventsourcing/model/types.go @@ -41,4 +41,11 @@ const ( OIDCConfigSecretChanged models.EventType = "project.application.config.oidc.secret.changed" OIDCClientSecretCheckSucceeded models.EventType = "project.application.oidc.secret.check.succeeded" OIDCClientSecretCheckFailed models.EventType = "project.application.oidc.secret.check.failed" + + APIConfigAdded models.EventType = "project.application.config.api.added" + APIConfigChanged models.EventType = "project.application.config.api.changed" + APIConfigSecretChanged models.EventType = "project.application.config.api.secret.changed" + + ClientKeyAdded models.EventType = "project.application.oidc.key.added" + ClientKeyRemoved models.EventType = "project.application.oidc.key.removed" ) diff --git a/internal/project/repository/eventsourcing/project.go b/internal/project/repository/eventsourcing/project.go index 5d41db2e4..363231612 100644 --- a/internal/project/repository/eventsourcing/project.go +++ b/internal/project/repository/eventsourcing/project.go @@ -36,6 +36,14 @@ func ProjectAggregate(ctx context.Context, aggCreator *es_models.AggregateCreato return aggCreator.NewAggregate(ctx, project.AggregateID, model.ProjectAggregate, model.ProjectVersion, project.Sequence) } +func ProjectAggregateOverwriteContext(ctx context.Context, aggCreator *es_models.AggregateCreator, project *model.Project, resourceOwnerID string, userID string) (*es_models.Aggregate, error) { + if project == nil { + return nil, errors.ThrowPreconditionFailed(nil, "EVENT-ADv2r", "Errors.Internal") + } + + return aggCreator.NewAggregate(ctx, project.AggregateID, model.ProjectAggregate, model.ProjectVersion, project.Sequence, es_models.OverwriteResourceOwner(resourceOwnerID), es_models.OverwriteEditorUser(userID)) +} + func ProjectCreateAggregate(aggCreator *es_models.AggregateCreator, project *model.Project, member *model.ProjectMember) func(ctx context.Context) (*es_models.Aggregate, error) { return func(ctx context.Context) (*es_models.Aggregate, error) { if project == nil || member == nil { @@ -229,6 +237,9 @@ func ApplicationAddedAggregate(aggCreator *es_models.AggregateCreator, existingP if app.OIDCConfig != nil { agg.AppendEvent(model.OIDCConfigAdded, app.OIDCConfig) } + if app.APIConfig != nil { + agg.AppendEvent(model.APIConfigAdded, app.APIConfig) + } return agg, nil } } @@ -322,6 +333,29 @@ func OIDCConfigChangedAggregate(aggCreator *es_models.AggregateCreator, existing } } +func APIConfigChangedAggregate(aggCreator *es_models.AggregateCreator, existingProject *model.Project, config *model.APIConfig) func(ctx context.Context) (*es_models.Aggregate, error) { + return func(ctx context.Context) (*es_models.Aggregate, error) { + if config == nil { + return nil, errors.ThrowPreconditionFailed(nil, "EVENT-slf32", "Errors.Internal") + } + agg, err := ProjectAggregate(ctx, aggCreator, existingProject) + if err != nil { + return nil, err + } + var changes map[string]interface{} + for _, a := range existingProject.Applications { + if a.AppID == config.AppID { + if a.APIConfig != nil { + changes = a.APIConfig.Changes(config) + } + } + } + agg.AppendEvent(model.APIConfigChanged, changes) + + return agg, nil + } +} + func OIDCConfigSecretChangedAggregate(aggCreator *es_models.AggregateCreator, existingProject *model.Project, appID string, secret *crypto.CryptoValue) func(ctx context.Context) (*es_models.Aggregate, error) { return func(ctx context.Context) (*es_models.Aggregate, error) { agg, err := ProjectAggregate(ctx, aggCreator, existingProject) @@ -338,6 +372,22 @@ func OIDCConfigSecretChangedAggregate(aggCreator *es_models.AggregateCreator, ex } } +func APIConfigSecretChangedAggregate(aggCreator *es_models.AggregateCreator, existingProject *model.Project, appID string, secret *crypto.CryptoValue) func(ctx context.Context) (*es_models.Aggregate, error) { + return func(ctx context.Context) (*es_models.Aggregate, error) { + agg, err := ProjectAggregate(ctx, aggCreator, existingProject) + if err != nil { + return nil, err + } + changes := make(map[string]interface{}, 2) + changes["appId"] = appID + changes["clientSecret"] = secret + + agg.AppendEvent(model.APIConfigSecretChanged, changes) + + return agg, nil + } +} + func OIDCClientSecretCheckSucceededAggregate(aggCreator *es_models.AggregateCreator, existingProject *model.Project, appID string) es_sdk.AggregateFunc { return func(ctx context.Context) (*es_models.Aggregate, error) { agg, err := ProjectAggregate(ctx, aggCreator, existingProject) @@ -368,6 +418,33 @@ func OIDCClientSecretCheckFailedAggregate(aggCreator *es_models.AggregateCreator } } +func OIDCApplicationKeyAddedAggregate(aggCreator *es_models.AggregateCreator, existingProject *model.Project, key *model.ClientKey) es_sdk.AggregateFunc { + return func(ctx context.Context) (*es_models.Aggregate, error) { + agg, err := ProjectAggregate(ctx, aggCreator, existingProject) + if err != nil { + return nil, err + } + agg.AppendEvent(model.ClientKeyAdded, key) + + return agg, nil + } +} + +func OIDCApplicationKeyRemovedAggregate(aggCreator *es_models.AggregateCreator, existingProject *model.Project, keyID string) es_sdk.AggregateFunc { + return func(ctx context.Context) (*es_models.Aggregate, error) { + agg, err := ProjectAggregate(ctx, aggCreator, existingProject) + if err != nil { + return nil, err + } + changes := make(map[string]interface{}, 1) + changes["keyId"] = keyID + + agg.AppendEvent(model.ClientKeyRemoved, changes) + + return agg, nil + } +} + func ProjectGrantAddedAggregate(aggCreator *es_models.AggregateCreator, project *model.Project, grant *model.ProjectGrant) func(ctx context.Context) (*es_models.Aggregate, error) { return func(ctx context.Context) (*es_models.Aggregate, error) { if grant == nil { diff --git a/internal/project/repository/view/model/application.go b/internal/project/repository/view/model/application.go index 9cfa7d268..fe682d8f0 100644 --- a/internal/project/repository/view/model/application.go +++ b/internal/project/repository/view/model/application.go @@ -116,17 +116,25 @@ func (a *ApplicationView) AppendEventIfMyApp(event *models.Event) (err error) { switch event.Type { case es_model.ApplicationAdded: err = view.SetData(event) + if err != nil { + return err + } case es_model.ApplicationChanged, es_model.OIDCConfigAdded, es_model.OIDCConfigChanged, + es_model.APIConfigAdded, + es_model.APIConfigChanged, es_model.ApplicationDeactivated, es_model.ApplicationReactivated: - err := view.SetData(event) + err = view.SetData(event) if err != nil { return err } case es_model.ApplicationRemoved: - return view.SetData(event) + err = view.SetData(event) + if err != nil { + return err + } case es_model.ProjectChanged: return a.AppendEvent(event) case es_model.ProjectRemoved: @@ -156,14 +164,20 @@ func (a *ApplicationView) AppendEvent(event *models.Event) (err error) { } a.setCompliance() return a.setOriginAllowList() - case es_model.OIDCConfigChanged, - es_model.ApplicationChanged: + case es_model.APIConfigAdded: + a.IsOIDC = false + return a.SetData(event) + case es_model.ApplicationChanged: + return a.SetData(event) + case es_model.OIDCConfigChanged: err = a.SetData(event) if err != nil { return err } a.setCompliance() return a.setOriginAllowList() + case es_model.APIConfigChanged: + return a.SetData(event) case es_model.ProjectChanged: return a.SetData(event) case es_model.ApplicationDeactivated: diff --git a/internal/static/i18n/de.yaml b/internal/static/i18n/de.yaml index 3e6472808..306a37c4a 100644 --- a/internal/static/i18n/de.yaml +++ b/internal/static/i18n/de.yaml @@ -189,10 +189,14 @@ Errors: Invalid: Applikation ist ungültig NotExisting: Applikation exisitert nicht IsNotOIDC: Applikation ist nicht vom Typ OIDC + IsNotAPI: Applikation ist nicht vom Typ API NotActive: Applikation ist nicht aktiv NotInactive: Applikation ist nickt inaktiv OIDCConfigInvalid: OIDC Konfiguration ist ungültig - OIDCAuthMethodNoneSecret: OIDC Auth Method None benötigt kein Secret + APIConfigInvalid: API Konfiguration ist ungültig + OIDCAuthMethodNoSecret: Gewählte OIDC Auth Method benötigt kein Secret + APIAuthMethodNoSecret: Gewählte API Auth Method benötigt kein Secret + AuthMethodNoPrivateKeyJWT: Gewählte Auth Method benötigt keinen Key RequiredFieldsMissing: Benötigte Felder fehlen Grant: AlreadyExists: Projekt Grant existiert bereits diff --git a/internal/static/i18n/en.yaml b/internal/static/i18n/en.yaml index 8c2a785e7..7a19e2f03 100644 --- a/internal/static/i18n/en.yaml +++ b/internal/static/i18n/en.yaml @@ -190,8 +190,13 @@ Errors: IsNotOIDC: Application is not type oidc NotActive:: Application is not active NotInactive: Application is not inactive - OIDCConfigInvalid: OIDC configuration is invalid - OIDCAuthMethodNoneSecret: OIDC Auth Method None does not require a secret + OIDCConfigInvalid: OIDC configuration is invalid + APIConfigInvalid: OIDC configuration is invalid + IsNotOIDC: Application is not type oidc + IsNotAPI: Application is not type API + OIDCAuthMethodNoSecret: Chosen OIDC Auth Method does not require a secret + APIAuthMethodNoSecret: Chosen API Auth Method does not require a secret + AuthMethodNoPrivateKeyJWT: Chosen Auth Method does not require a key RequiredFieldsMissing: Some required fields are missing Grant: AlreadyExists: Project grant already exists diff --git a/internal/ui/login/handler/external_login_handler.go b/internal/ui/login/handler/external_login_handler.go index c64031981..789d1d905 100644 --- a/internal/ui/login/handler/external_login_handler.go +++ b/internal/ui/login/handler/external_login_handler.go @@ -1,8 +1,8 @@ package handler import ( + "github.com/caos/oidc/pkg/client/rp" "github.com/caos/oidc/pkg/oidc" - "github.com/caos/oidc/pkg/rp" http_mw "github.com/caos/zitadel/internal/api/http/middleware" "github.com/caos/zitadel/internal/crypto" "github.com/caos/zitadel/internal/errors" @@ -113,13 +113,13 @@ func (l *Login) handleExternalLoginCallback(w http.ResponseWriter, r *http.Reque l.handleExternalUserAuthenticated(w, r, authReq, idpConfig, userAgentID, tokens) } -func (l *Login) getRPConfig(w http.ResponseWriter, r *http.Request, authReq *domain.AuthRequest, idpConfig *iam_model.IDPConfigView, callbackEndpoint string) rp.RelayingParty { +func (l *Login) getRPConfig(w http.ResponseWriter, r *http.Request, authReq *domain.AuthRequest, idpConfig *iam_model.IDPConfigView, callbackEndpoint string) rp.RelyingParty { oidcClientSecret, err := crypto.DecryptString(idpConfig.OIDCClientSecret, l.IDPConfigAesCrypto) if err != nil { l.renderError(w, r, authReq, err) return nil } - provider, err := rp.NewRelayingPartyOIDC(idpConfig.OIDCIssuer, idpConfig.OIDCClientID, oidcClientSecret, l.baseURL+callbackEndpoint, idpConfig.OIDCScopes, rp.WithVerifierOpts(rp.WithIssuedAtOffset(3*time.Second))) + provider, err := rp.NewRelyingPartyOIDC(idpConfig.OIDCIssuer, idpConfig.OIDCClientID, oidcClientSecret, l.baseURL+callbackEndpoint, idpConfig.OIDCScopes, rp.WithVerifierOpts(rp.WithIssuedAtOffset(3*time.Second))) if err != nil { l.renderError(w, r, authReq, err) return nil diff --git a/internal/ui/login/handler/external_register_handler.go b/internal/ui/login/handler/external_register_handler.go index b1907df24..4d5f63acc 100644 --- a/internal/ui/login/handler/external_register_handler.go +++ b/internal/ui/login/handler/external_register_handler.go @@ -1,15 +1,16 @@ package handler import ( - "github.com/caos/zitadel/internal/v2/domain" "net/http" "strings" + "github.com/caos/oidc/pkg/client/rp" "github.com/caos/oidc/pkg/oidc" - "github.com/caos/oidc/pkg/rp" + http_mw "github.com/caos/zitadel/internal/api/http/middleware" caos_errors "github.com/caos/zitadel/internal/errors" iam_model "github.com/caos/zitadel/internal/iam/model" + "github.com/caos/zitadel/internal/v2/domain" ) func (l *Login) handleExternalRegister(w http.ResponseWriter, r *http.Request) { diff --git a/internal/ui/login/static/resources/scripts/form_submit.js b/internal/ui/login/static/resources/scripts/form_submit.js index ddf94f0b1..b822c4c35 100644 --- a/internal/ui/login/static/resources/scripts/form_submit.js +++ b/internal/ui/login/static/resources/scripts/form_submit.js @@ -6,6 +6,8 @@ function disableSubmit(checks, button) { } addRequiredEventListener(inputs, checks, form, button); disableDoubleSubmit(form, button); + + toggleButton(checks, form, inputs, button); } function addRequiredEventListener(inputs, checks, form, button) { diff --git a/internal/ui/login/static/resources/scripts/loginname_suffix.js b/internal/ui/login/static/resources/scripts/loginname_suffix.js index 9e8ce2c5e..c4aa938bb 100644 --- a/internal/ui/login/static/resources/scripts/loginname_suffix.js +++ b/internal/ui/login/static/resources/scripts/loginname_suffix.js @@ -10,6 +10,8 @@ function RenderDefaultLoginnameSuffix() { } else { defaultLoginNameSuffix.innerText = ""; } + + offsetLabel(); } window.addEventListener('DOMContentLoaded', (event) => { @@ -19,3 +21,18 @@ window.addEventListener('DOMContentLoaded', (event) => { document.getElementById("orgname").addEventListener('input', function () { RenderDefaultLoginnameSuffix(); }); + +function offsetLabel() { + const suffix = document.getElementById('default-login-suffix'); + const suffixInput = document.getElementsByClassName('lgn-suffix-input')[0]; + + calculateOffset(); + suffix.addEventListener("DOMCharacterDataModified", calculateOffset); + + function calculateOffset() { + // add suffix width to inner right padding of the input field + if (suffix && suffixInput) { + suffixInput.style.paddingRight = `${(suffix.offsetWidth ?? 0) + 10}px`; + } + } +} \ No newline at end of file diff --git a/internal/ui/login/static/resources/themes/scss/styles/account_selection/account_selection.scss b/internal/ui/login/static/resources/themes/scss/styles/account_selection/account_selection.scss index c090205d7..a4d8ac04a 100644 --- a/internal/ui/login/static/resources/themes/scss/styles/account_selection/account_selection.scss +++ b/internal/ui/login/static/resources/themes/scss/styles/account_selection/account_selection.scss @@ -21,16 +21,21 @@ $lgn-container-margin: 0px auto 50px auto; display: block; margin: .5rem; text-align: start; + overflow: hidden; .lgn-displayname{ font-size: 16px; margin: .5rem 0; margin-bottom: 0; + text-overflow: ellipsis; + overflow: hidden; } .lgn-loginname{ font-size: 14px; margin: 0; + text-overflow: ellipsis; + overflow: hidden; } .lgn-session-state { diff --git a/internal/ui/login/static/resources/themes/zitadel/css/bundle.css b/internal/ui/login/static/resources/themes/zitadel/css/bundle.css index 3d864d032..d21ea24fe 100644 --- a/internal/ui/login/static/resources/themes/zitadel/css/bundle.css +++ b/internal/ui/login/static/resources/themes/zitadel/css/bundle.css @@ -448,15 +448,20 @@ i { display: block; margin: 0.5rem; text-align: start; + overflow: hidden; } .lgn-account-selection .lgn-account .lgn-names .lgn-displayname { font-size: 16px; margin: 0.5rem 0; margin-bottom: 0; + text-overflow: ellipsis; + overflow: hidden; } .lgn-account-selection .lgn-account .lgn-names .lgn-loginname { font-size: 14px; margin: 0; + text-overflow: ellipsis; + overflow: hidden; } .lgn-account-selection .lgn-account .lgn-names .lgn-session-state { margin: 0; @@ -1301,15 +1306,20 @@ i { display: block; margin: 0.5rem; text-align: start; + overflow: hidden; } .lgn-account-selection .lgn-account .lgn-names .lgn-displayname { font-size: 16px; margin: 0.5rem 0; margin-bottom: 0; + text-overflow: ellipsis; + overflow: hidden; } .lgn-account-selection .lgn-account .lgn-names .lgn-loginname { font-size: 14px; margin: 0; + text-overflow: ellipsis; + overflow: hidden; } .lgn-account-selection .lgn-account .lgn-names .lgn-session-state { margin: 0; diff --git a/internal/ui/login/static/resources/themes/zitadel/css/bundle.css.map b/internal/ui/login/static/resources/themes/zitadel/css/bundle.css.map index b889956c7..b21900164 100644 --- a/internal/ui/login/static/resources/themes/zitadel/css/bundle.css.map +++ b/internal/ui/login/static/resources/themes/zitadel/css/bundle.css.map @@ -1 +1 @@ -{"version":3,"sourceRoot":"","sources":["../../scss/styles/footer/footer.scss","../../scss/styles/header/header.scss","../../scss/styles/button/button.scss","../../scss/styles/button/button_base.scss","../../scss/styles/input/input.scss","../../scss/styles/input/input_base.scss","../../scss/styles/label/label.scss","../../scss/styles/label/label_base.scss","../../scss/styles/radio/radio_base.scss","../../scss/styles/radio/radio.scss","../../scss/styles/a/a.scss","../../scss/styles/identity_provider/identity_provider.scss","../../scss/styles/identity_provider/identity_provider_base.scss","../../scss/styles/error/error.scss","../../scss/styles/qrcode/qrcode.scss","../../scss/styles/container/container.scss","../../scss/styles/account_selection/account_selection.scss","../../scss/styles/avatar/avatar.scss","../../scss/styles/checkbox/checkbox.scss","../../scss/styles/checkbox/checkbox_base.scss","../../scss/styles/select/select.scss","../../scss/styles/select/select_base.scss","../../scss/styles/list/list_base.scss","../../scss/styles/typography/faces/ailerons_font_faces.scss","../../scss/styles/typography/faces/lato_font_faces.scss","../../scss/styles/typography/faces/roboto_font_faces.scss","../../scss/styles/typography/faces/raleway_font_faces.scss","../../scss/styles/typography/faces/pt_sans_font_faces.scss","../../scss/styles/success_label/success_label.scss","../../scss/styles/register/register.scss","../../scss/styles/animations.scss"],"names":[],"mappings":";AAIA;EACI;EACA;EACA;EACA,YAPY;EAQZ;EACA;EACA,SATa;;AAWb;EACI;;AAGJ;EACI;EACA;;AAGJ;EAlBJ;IAmBQ;IACA;IACA;IACA;;;;ACvBR;EACI;EACA;EACA,QALgB;EAMhB,SAPiB;EAQjB;;AAEA;EACI;EACA;EACA;;;ACXR;ECkBE;EACA;EACA;EACA;EACA;EACA;EAGA;EACA;EACA;EACA;EACA;EAGA,QAjCkB;EAkClB,WAnCqB;EAoCrB,aAlCuB;EAmCvB,SAtCmB;EAuCnB,eAnCyB;EAqCzB;;AAEA;EACE;;AAGF;EACE;;;AD1CJ;ECcE;EACA;EACA;EACA;EACA;EACA;EAGA;EACA;EACA;EACA;EACA;EAGA,QAjCkB;EAkClB,WAnCqB;EAoCrB,aAlCuB;EAmCvB,SAtCmB;EAuCnB,eAnCyB;EAqCzB;EAgBA;;AAdA;EACE;;AAGF;EACE;;;ADtCJ;EACE;EACA;EACA,OCCqB;EDArB;EACA;EACA,aCFqB;EDGrB,eCF8B;;ADI9B;EACE,aCJ0B;;;ADQ9B;EACE;EACA,SCf2B;EDgB3B,aCjB+B;;;ADoBjC;EACE;EACA,YC3B4B;;;AD+B5B;EACE;;;AEnCJ;AAAA;ECOI;EACA;EACA,sBAXsB;EAYtB;EACA;EACA;EACA;EACA,eAZsB;EAatB;EACA;EACA;EACA,cAfqB;EAgBrB,QAlBoB;EAmBpB,SArBgB;EAsBhB;EACA;EACA,QAvBe;;AAyBf;AAAA;EACI,WAtB0B;EAuB1B;;;ADrBR;ECCI;EACA;EACA,sBAXsB;EAYtB;EACA;EACA;EACA;EACA,eAZsB;EAatB;EACA;EACA;EACA,cAfqB;EAgBrB,QAlBoB;EAmBpB,SArBgB;EAsBhB;EACA;EACA,QAvBe;;AAyBf;EACI,WAtB0B;EAuB1B;;;ADjBR;EACI;;AAEA;EACI;EACA;EACA;EACA;EACA;;;AElBR;ECGI;EACA,WANkB;EAOlB;EACA,QAPe;EAQf,aAPoB;;;ACMxB;EACI;IACE;;EAGF;IACE;;EAGF;IACE;;;AChBN;EDqBI;EACA;EACA;;AAEA;EACI;;AAGJ;EACI;EACA,QA9BS;EA+BT;EACA,SA7BkB;EA8BlB;EACA;EACA;EACA;EACA;EACA,WAzCc;EA0Cd;;AAEA;EAEI;EACA;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA,OArDK;EAsDL,QAtDK;EAuDL;EACA;;AAGJ;EACI;EACA;EACA,OA7Da;EA8Db,QA9Da;EA+Db;;AAIR;EACI;EACA;EACA;EACA;EACA;;AAEA;EACI;;AAGJ;EACI;;AAGJ;EACI;;AAOA;EACI;EACA;;AAGJ;EACI;;AAKZ;AAAA;AAAA;EAGI;;;AE5GR;EACI;EACA;EACA;EACA;;AAEA;EACI;;;ACLR;ECKI;EACA,QARa;EASb;EACA;EACA;EACA;EACA,SAZc;EAad,eAXoB;EAYpB;EACA;;AAEA;EACI;EACA;;AAGJ;EACI,aAtB4B;EAuB5B;EACA;EACA;;AAIA;EACI;EACA;EACA;EACA;EACA;EACA;EACA;;;ACtCZ;EACI;EACA;EACA;;AACA;EACI;EACA;;;ACNR;EACI;EACA;EACA;EACA;;AAEA;EACI;EACA;EACA;;;ACHR;EACI,WAPsB;EAQtB;EACA;EACA,eAN0B;EAO1B;;AAEA;EAPJ;IAQQ,YAXmB;;;;AAe3B;EACI;EACA;EACA,QAnBmB;EAoBnB,SArBoB;EAsBpB;EACA;;AAGI;EACI;;AAGJ;EACI;;AAIR;EACI;EACA;EACA;EACA;;AAIA;EACI;;AAGJ;EACI;;AAIR;EACI;EACA;EACA;;AAIA;EACI;;AAGJ;EACI;;AAIR;EACI;;AAEA;EACI;EACA;;AAEJ;EACI;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;;AAGJ;EACI;;AAGA;EACI;;AAMhB;EACI;EACA;EACA;;AAGJ;EACI;EACA;;AAGJ;EACI;EACA;;AAEA;EACI;EACA;;;AAKZ;EACI;;;ACtHJ;EACI;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA;;AAEA;EACI;;AAGJ;EACI;EACA;EACA;;AAEA;EACI;EACA;EACA;;AAGJ;EACI;EACA;;AAGJ;EACI;EACA;EACA;;AAIR;EACI;;AAGJ;EACI;;;AC3CZ;EACI,QAHc;EAId,OAJc;EAKd;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;ACdJ;ECCI;EACA;EACA;EACA,WANqB;EAOrB;EACA;;AAEA;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAIJ;EACI;EACA;EACA;EACA;EACA,WA3BiB;EA4BjB;;AAEA;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AChDZ;ECCI;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACI;;;ACVJ;EACI;EACA;;AAEA;EACI;;AAIR;EACI;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;;AAKJ;EACI;EACA;EACA;EACA;EACA;EACA;;AAIR;EACI;EACA;;;ACpCR;EACI;EACA;;ACFJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AC7DJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;ACzEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AC9GJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;ACtBJ;EACI;EACA;EACA;EACA;;;A5BFJ;EACI;EACA;EACA;EACA,YAPY;EAQZ;EACA;EACA,SATa;;AAWb;EACI;;AAGJ;EACI;EACA;;AAGJ;EAlBJ;IAmBQ;IACA;IACA;IACA;;;;ACvBR;EACI;EACA;EACA,QALgB;EAMhB,SAPiB;EAQjB;;AAEA;EACI;EACA;EACA;;;ACXR;ECkBE;EACA;EACA;EACA;EACA;EACA;EAGA;EACA;EACA;EACA;EACA;EAGA,QAjCkB;EAkClB,WAnCqB;EAoCrB,aAlCuB;EAmCvB,SAtCmB;EAuCnB,eAnCyB;EAqCzB;;AAEA;EACE;;AAGF;EACE;;;AD1CJ;ECcE;EACA;EACA;EACA;EACA;EACA;EAGA;EACA;EACA;EACA;EACA;EAGA,QAjCkB;EAkClB,WAnCqB;EAoCrB,aAlCuB;EAmCvB,SAtCmB;EAuCnB,eAnCyB;EAqCzB;EAgBA;;AAdA;EACE;;AAGF;EACE;;;ADtCJ;EACE;EACA;EACA,OCCqB;EDArB;EACA;EACA,aCFqB;EDGrB,eCF8B;;ADI9B;EACE,aCJ0B;;;ADQ9B;EACE;EACA,SCf2B;EDgB3B,aCjB+B;;;ADoBjC;EACE;EACA,YC3B4B;;;AD+B5B;EACE;;;AEnCJ;AAAA;ECOI;EACA;EACA,sBAXsB;EAYtB;EACA;EACA;EACA;EACA,eAZsB;EAatB;EACA;EACA;EACA,cAfqB;EAgBrB,QAlBoB;EAmBpB,SArBgB;EAsBhB;EACA;EACA,QAvBe;;AAyBf;AAAA;EACI,WAtB0B;EAuB1B;;;ADrBR;ECCI;EACA;EACA,sBAXsB;EAYtB;EACA;EACA;EACA;EACA,eAZsB;EAatB;EACA;EACA;EACA,cAfqB;EAgBrB,QAlBoB;EAmBpB,SArBgB;EAsBhB;EACA;EACA,QAvBe;;AAyBf;EACI,WAtB0B;EAuB1B;;;ADjBR;EACI;;AAEA;EACI;EACA;EACA;EACA;EACA;;;AElBR;ECGI;EACA,WANkB;EAOlB;EACA,QAPe;EAQf,aAPoB;;;ACMxB;EACI;IACE;;EAGF;IACE;;EAGF;IACE;;;AChBN;EDqBI;EACA;EACA;;AAEA;EACI;;AAGJ;EACI;EACA,QA9BS;EA+BT;EACA,SA7BkB;EA8BlB;EACA;EACA;EACA;EACA;EACA,WAzCc;EA0Cd;;AAEA;EAEI;EACA;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA,OArDK;EAsDL,QAtDK;EAuDL;EACA;;AAGJ;EACI;EACA;EACA,OA7Da;EA8Db,QA9Da;EA+Db;;AAIR;EACI;EACA;EACA;EACA;EACA;;AAEA;EACI;;AAGJ;EACI;;AAGJ;EACI;;AAOA;EACI;EACA;;AAGJ;EACI;;AAKZ;AAAA;AAAA;EAGI;;;AE5GR;EACI;EACA;EACA;EACA;;AAEA;EACI;;;ACLR;ECKI;EACA,QARa;EASb;EACA;EACA;EACA;EACA,SAZc;EAad,eAXoB;EAYpB;EACA;;AAEA;EACI;EACA;;AAGJ;EACI,aAtB4B;EAuB5B;EACA;EACA;;AAIA;EACI;EACA;EACA;EACA;EACA;EACA;EACA;;;ACtCZ;EACI;EACA;EACA;;AACA;EACI;EACA;;;ACNR;EACI;EACA;EACA;EACA;;AAEA;EACI;EACA;EACA;;;ACHR;EACI,WAPsB;EAQtB;EACA;EACA,eAN0B;EAO1B;;AAEA;EAPJ;IAQQ,YAXmB;;;;AAe3B;EACI;EACA;EACA,QAnBmB;EAoBnB,SArBoB;EAsBpB;EACA;;AAGI;EACI;;AAGJ;EACI;;AAIR;EACI;EACA;EACA;EACA;;AAIA;EACI;;AAGJ;EACI;;AAIR;EACI;EACA;EACA;;AAIA;EACI;;AAGJ;EACI;;AAIR;EACI;;AAEA;EACI;EACA;;AAEJ;EACI;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;;AAGJ;EACI;;AAGA;EACI;;AAMhB;EACI;EACA;EACA;;AAGJ;EACI;EACA;;AAGJ;EACI;EACA;;AAEA;EACI;EACA;;;AAKZ;EACI;;;ACtHJ;EACI;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA;;AAEA;EACI;;AAGJ;EACI;EACA;EACA;;AAEA;EACI;EACA;EACA;;AAGJ;EACI;EACA;;AAGJ;EACI;EACA;EACA;;AAIR;EACI;;AAGJ;EACI;;;AC3CZ;EACI,QAHc;EAId,OAJc;EAKd;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;ACdJ;ECCI;EACA;EACA;EACA,WANqB;EAOrB;EACA;;AAEA;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAIJ;EACI;EACA;EACA;EACA;EACA,WA3BiB;EA4BjB;;AAEA;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AChDZ;ECCI;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACI;;;ACVJ;EACI;EACA;;AAEA;EACI;;AAIR;EACI;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;;AAKJ;EACI;EACA;EACA;EACA;EACA;EACA;;AAIR;EACI;EACA;;;ACpCR;EACI;EACA;;ACFJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AC7DJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;ACzEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AC9GJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;ACtBJ;EACI;EACA;EACA;EACA;;;ALNJ;EACI;EACA;;ACFJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AC7DJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;ACzEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AC9GJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AZlBJ;EACI,WAPsB;EAQtB;EACA;EACA,eAN0B;EAO1B;;AAEA;EAPJ;IAQQ,YAXmB;;;;AAe3B;EACI;EACA;EACA,QAnBmB;EAoBnB,SArBoB;EAsBpB;EACA;;AAGI;EACI;;AAGJ;EACI;;AAIR;EACI;EACA;EACA;EACA;;AAIA;EACI;;AAGJ;EACI;;AAIR;EACI;EACA;EACA;;AAIA;EACI;;AAGJ;EACI;;AAIR;EACI;;AAEA;EACI;EACA;;AAEJ;EACI;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;;AAGJ;EACI;;AAGA;EACI;;AAMhB;EACI;EACA;EACA;;AAGJ;EACI;EACA;;AAGJ;EACI;EACA;;AAEA;EACI;EACA;;;AAKZ;EACI;;;AcvHA;EACI;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA;;AAIR;EACI;;;A5BdR;EACI;EACA;EACA,QALgB;EAMhB,SAPiB;EAQjB;;AAEA;EACI;EACA;EACA;;;A6BbR;EACI;IACE;;EAGF;IACE;;EAGF;IACE;;EAGF;IACE;;;AAIN;EACI;EACA","file":"bundle.css"} \ No newline at end of file +{"version":3,"sourceRoot":"","sources":["../../scss/styles/footer/footer.scss","../../scss/styles/header/header.scss","../../scss/styles/button/button.scss","../../scss/styles/button/button_base.scss","../../scss/styles/input/input.scss","../../scss/styles/input/input_base.scss","../../scss/styles/label/label.scss","../../scss/styles/label/label_base.scss","../../scss/styles/radio/radio_base.scss","../../scss/styles/radio/radio.scss","../../scss/styles/a/a.scss","../../scss/styles/identity_provider/identity_provider.scss","../../scss/styles/identity_provider/identity_provider_base.scss","../../scss/styles/error/error.scss","../../scss/styles/qrcode/qrcode.scss","../../scss/styles/container/container.scss","../../scss/styles/account_selection/account_selection.scss","../../scss/styles/avatar/avatar.scss","../../scss/styles/checkbox/checkbox.scss","../../scss/styles/checkbox/checkbox_base.scss","../../scss/styles/select/select.scss","../../scss/styles/select/select_base.scss","../../scss/styles/list/list_base.scss","../../scss/styles/typography/faces/ailerons_font_faces.scss","../../scss/styles/typography/faces/lato_font_faces.scss","../../scss/styles/typography/faces/roboto_font_faces.scss","../../scss/styles/typography/faces/raleway_font_faces.scss","../../scss/styles/typography/faces/pt_sans_font_faces.scss","../../scss/styles/success_label/success_label.scss","../../scss/styles/register/register.scss","../../scss/styles/animations.scss"],"names":[],"mappings":";AAIA;EACI;EACA;EACA;EACA,YAPY;EAQZ;EACA;EACA,SATa;;AAWb;EACI;;AAGJ;EACI;EACA;;AAGJ;EAlBJ;IAmBQ;IACA;IACA;IACA;;;;ACvBR;EACI;EACA;EACA,QALgB;EAMhB,SAPiB;EAQjB;;AAEA;EACI;EACA;EACA;;;ACXR;ECkBE;EACA;EACA;EACA;EACA;EACA;EAGA;EACA;EACA;EACA;EACA;EAGA,QAjCkB;EAkClB,WAnCqB;EAoCrB,aAlCuB;EAmCvB,SAtCmB;EAuCnB,eAnCyB;EAqCzB;;AAEA;EACE;;AAGF;EACE;;;AD1CJ;ECcE;EACA;EACA;EACA;EACA;EACA;EAGA;EACA;EACA;EACA;EACA;EAGA,QAjCkB;EAkClB,WAnCqB;EAoCrB,aAlCuB;EAmCvB,SAtCmB;EAuCnB,eAnCyB;EAqCzB;EAgBA;;AAdA;EACE;;AAGF;EACE;;;ADtCJ;EACE;EACA;EACA,OCCqB;EDArB;EACA;EACA,aCFqB;EDGrB,eCF8B;;ADI9B;EACE,aCJ0B;;;ADQ9B;EACE;EACA,SCf2B;EDgB3B,aCjB+B;;;ADoBjC;EACE;EACA,YC3B4B;;;AD+B5B;EACE;;;AEnCJ;AAAA;ECOI;EACA;EACA,sBAXsB;EAYtB;EACA;EACA;EACA;EACA,eAZsB;EAatB;EACA;EACA;EACA,cAfqB;EAgBrB,QAlBoB;EAmBpB,SArBgB;EAsBhB;EACA;EACA,QAvBe;;AAyBf;AAAA;EACI,WAtB0B;EAuB1B;;;ADrBR;ECCI;EACA;EACA,sBAXsB;EAYtB;EACA;EACA;EACA;EACA,eAZsB;EAatB;EACA;EACA;EACA,cAfqB;EAgBrB,QAlBoB;EAmBpB,SArBgB;EAsBhB;EACA;EACA,QAvBe;;AAyBf;EACI,WAtB0B;EAuB1B;;;ADjBR;EACI;;AAEA;EACI;EACA;EACA;EACA;EACA;;;AElBR;ECGI;EACA,WANkB;EAOlB;EACA,QAPe;EAQf,aAPoB;;;ACMxB;EACI;IACE;;EAGF;IACE;;EAGF;IACE;;;AChBN;EDqBI;EACA;EACA;;AAEA;EACI;;AAGJ;EACI;EACA,QA9BS;EA+BT;EACA,SA7BkB;EA8BlB;EACA;EACA;EACA;EACA;EACA,WAzCc;EA0Cd;;AAEA;EAEI;EACA;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA,OArDK;EAsDL,QAtDK;EAuDL;EACA;;AAGJ;EACI;EACA;EACA,OA7Da;EA8Db,QA9Da;EA+Db;;AAIR;EACI;EACA;EACA;EACA;EACA;;AAEA;EACI;;AAGJ;EACI;;AAGJ;EACI;;AAOA;EACI;EACA;;AAGJ;EACI;;AAKZ;AAAA;AAAA;EAGI;;;AE5GR;EACI;EACA;EACA;EACA;;AAEA;EACI;;;ACLR;ECKI;EACA,QARa;EASb;EACA;EACA;EACA;EACA,SAZc;EAad,eAXoB;EAYpB;EACA;;AAEA;EACI;EACA;;AAGJ;EACI,aAtB4B;EAuB5B;EACA;EACA;;AAIA;EACI;EACA;EACA;EACA;EACA;EACA;EACA;;;ACtCZ;EACI;EACA;EACA;;AACA;EACI;EACA;;;ACNR;EACI;EACA;EACA;EACA;;AAEA;EACI;EACA;EACA;;;ACHR;EACI,WAPsB;EAQtB;EACA;EACA,eAN0B;EAO1B;;AAEA;EAPJ;IAQQ,YAXmB;;;;AAe3B;EACI;EACA;EACA,QAnBmB;EAoBnB,SArBoB;EAsBpB;EACA;;AAGI;EACI;;AAGJ;EACI;;AAIR;EACI;EACA;EACA;EACA;;AAIA;EACI;;AAGJ;EACI;;AAIR;EACI;EACA;EACA;;AAIA;EACI;;AAGJ;EACI;;AAIR;EACI;;AAEA;EACI;EACA;;AAEJ;EACI;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;;AAGJ;EACI;;AAGA;EACI;;AAMhB;EACI;EACA;EACA;;AAGJ;EACI;EACA;;AAGJ;EACI;EACA;;AAEA;EACI;EACA;;;AAKZ;EACI;;;ACtHJ;EACI;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA;;AAEA;EACI;;AAGJ;EACI;EACA;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;;AAIR;EACI;;AAGJ;EACI;;;AChDZ;EACI,QAHc;EAId,OAJc;EAKd;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;ACdJ;ECCI;EACA;EACA;EACA,WANqB;EAOrB;EACA;;AAEA;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAIJ;EACI;EACA;EACA;EACA;EACA,WA3BiB;EA4BjB;;AAEA;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AChDZ;ECCI;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACI;;;ACVJ;EACI;EACA;;AAEA;EACI;;AAIR;EACI;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;;AAKJ;EACI;EACA;EACA;EACA;EACA;EACA;;AAIR;EACI;EACA;;;ACpCR;EACI;EACA;;ACFJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AC7DJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;ACzEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AC9GJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;ACtBJ;EACI;EACA;EACA;EACA;;;A5BFJ;EACI;EACA;EACA;EACA,YAPY;EAQZ;EACA;EACA,SATa;;AAWb;EACI;;AAGJ;EACI;EACA;;AAGJ;EAlBJ;IAmBQ;IACA;IACA;IACA;;;;ACvBR;EACI;EACA;EACA,QALgB;EAMhB,SAPiB;EAQjB;;AAEA;EACI;EACA;EACA;;;ACXR;ECkBE;EACA;EACA;EACA;EACA;EACA;EAGA;EACA;EACA;EACA;EACA;EAGA,QAjCkB;EAkClB,WAnCqB;EAoCrB,aAlCuB;EAmCvB,SAtCmB;EAuCnB,eAnCyB;EAqCzB;;AAEA;EACE;;AAGF;EACE;;;AD1CJ;ECcE;EACA;EACA;EACA;EACA;EACA;EAGA;EACA;EACA;EACA;EACA;EAGA,QAjCkB;EAkClB,WAnCqB;EAoCrB,aAlCuB;EAmCvB,SAtCmB;EAuCnB,eAnCyB;EAqCzB;EAgBA;;AAdA;EACE;;AAGF;EACE;;;ADtCJ;EACE;EACA;EACA,OCCqB;EDArB;EACA;EACA,aCFqB;EDGrB,eCF8B;;ADI9B;EACE,aCJ0B;;;ADQ9B;EACE;EACA,SCf2B;EDgB3B,aCjB+B;;;ADoBjC;EACE;EACA,YC3B4B;;;AD+B5B;EACE;;;AEnCJ;AAAA;ECOI;EACA;EACA,sBAXsB;EAYtB;EACA;EACA;EACA;EACA,eAZsB;EAatB;EACA;EACA;EACA,cAfqB;EAgBrB,QAlBoB;EAmBpB,SArBgB;EAsBhB;EACA;EACA,QAvBe;;AAyBf;AAAA;EACI,WAtB0B;EAuB1B;;;ADrBR;ECCI;EACA;EACA,sBAXsB;EAYtB;EACA;EACA;EACA;EACA,eAZsB;EAatB;EACA;EACA;EACA,cAfqB;EAgBrB,QAlBoB;EAmBpB,SArBgB;EAsBhB;EACA;EACA,QAvBe;;AAyBf;EACI,WAtB0B;EAuB1B;;;ADjBR;EACI;;AAEA;EACI;EACA;EACA;EACA;EACA;;;AElBR;ECGI;EACA,WANkB;EAOlB;EACA,QAPe;EAQf,aAPoB;;;ACMxB;EACI;IACE;;EAGF;IACE;;EAGF;IACE;;;AChBN;EDqBI;EACA;EACA;;AAEA;EACI;;AAGJ;EACI;EACA,QA9BS;EA+BT;EACA,SA7BkB;EA8BlB;EACA;EACA;EACA;EACA;EACA,WAzCc;EA0Cd;;AAEA;EAEI;EACA;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA,OArDK;EAsDL,QAtDK;EAuDL;EACA;;AAGJ;EACI;EACA;EACA,OA7Da;EA8Db,QA9Da;EA+Db;;AAIR;EACI;EACA;EACA;EACA;EACA;;AAEA;EACI;;AAGJ;EACI;;AAGJ;EACI;;AAOA;EACI;EACA;;AAGJ;EACI;;AAKZ;AAAA;AAAA;EAGI;;;AE5GR;EACI;EACA;EACA;EACA;;AAEA;EACI;;;ACLR;ECKI;EACA,QARa;EASb;EACA;EACA;EACA;EACA,SAZc;EAad,eAXoB;EAYpB;EACA;;AAEA;EACI;EACA;;AAGJ;EACI,aAtB4B;EAuB5B;EACA;EACA;;AAIA;EACI;EACA;EACA;EACA;EACA;EACA;EACA;;;ACtCZ;EACI;EACA;EACA;;AACA;EACI;EACA;;;ACNR;EACI;EACA;EACA;EACA;;AAEA;EACI;EACA;EACA;;;ACHR;EACI,WAPsB;EAQtB;EACA;EACA,eAN0B;EAO1B;;AAEA;EAPJ;IAQQ,YAXmB;;;;AAe3B;EACI;EACA;EACA,QAnBmB;EAoBnB,SArBoB;EAsBpB;EACA;;AAGI;EACI;;AAGJ;EACI;;AAIR;EACI;EACA;EACA;EACA;;AAIA;EACI;;AAGJ;EACI;;AAIR;EACI;EACA;EACA;;AAIA;EACI;;AAGJ;EACI;;AAIR;EACI;;AAEA;EACI;EACA;;AAEJ;EACI;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;;AAGJ;EACI;;AAGA;EACI;;AAMhB;EACI;EACA;EACA;;AAGJ;EACI;EACA;;AAGJ;EACI;EACA;;AAEA;EACI;EACA;;;AAKZ;EACI;;;ACtHJ;EACI;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA;;AAEA;EACI;;AAGJ;EACI;EACA;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;;AAIR;EACI;;AAGJ;EACI;;;AChDZ;EACI,QAHc;EAId,OAJc;EAKd;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;ACdJ;ECCI;EACA;EACA;EACA,WANqB;EAOrB;EACA;;AAEA;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAIJ;EACI;EACA;EACA;EACA;EACA,WA3BiB;EA4BjB;;AAEA;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AChDZ;ECCI;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACI;;;ACVJ;EACI;EACA;;AAEA;EACI;;AAIR;EACI;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;;AAKJ;EACI;EACA;EACA;EACA;EACA;EACA;;AAIR;EACI;EACA;;;ACpCR;EACI;EACA;;ACFJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AC7DJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;ACzEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AC9GJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;ACtBJ;EACI;EACA;EACA;EACA;;;ALNJ;EACI;EACA;;ACFJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AC7DJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;ACzEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AC9GJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AZlBJ;EACI,WAPsB;EAQtB;EACA;EACA,eAN0B;EAO1B;;AAEA;EAPJ;IAQQ,YAXmB;;;;AAe3B;EACI;EACA;EACA,QAnBmB;EAoBnB,SArBoB;EAsBpB;EACA;;AAGI;EACI;;AAGJ;EACI;;AAIR;EACI;EACA;EACA;EACA;;AAIA;EACI;;AAGJ;EACI;;AAIR;EACI;EACA;EACA;;AAIA;EACI;;AAGJ;EACI;;AAIR;EACI;;AAEA;EACI;EACA;;AAEJ;EACI;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;;AAGJ;EACI;;AAGA;EACI;;AAMhB;EACI;EACA;EACA;;AAGJ;EACI;EACA;;AAGJ;EACI;EACA;;AAEA;EACI;EACA;;;AAKZ;EACI;;;AcvHA;EACI;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA;;AAIR;EACI;;;A5BdR;EACI;EACA;EACA,QALgB;EAMhB,SAPiB;EAQjB;;AAEA;EACI;EACA;EACA;;;A6BbR;EACI;IACE;;EAGF;IACE;;EAGF;IACE;;EAGF;IACE;;;AAIN;EACI;EACA","file":"bundle.css"} \ No newline at end of file diff --git a/internal/ui/login/static/resources/themes/zitadel/css/zitadel.css b/internal/ui/login/static/resources/themes/zitadel/css/zitadel.css index 318ea5e85..b8feec19b 100644 --- a/internal/ui/login/static/resources/themes/zitadel/css/zitadel.css +++ b/internal/ui/login/static/resources/themes/zitadel/css/zitadel.css @@ -448,15 +448,20 @@ i { display: block; margin: 0.5rem; text-align: start; + overflow: hidden; } .lgn-account-selection .lgn-account .lgn-names .lgn-displayname { font-size: 16px; margin: 0.5rem 0; margin-bottom: 0; + text-overflow: ellipsis; + overflow: hidden; } .lgn-account-selection .lgn-account .lgn-names .lgn-loginname { font-size: 14px; margin: 0; + text-overflow: ellipsis; + overflow: hidden; } .lgn-account-selection .lgn-account .lgn-names .lgn-session-state { margin: 0; diff --git a/internal/ui/login/static/resources/themes/zitadel/css/zitadel.css.map b/internal/ui/login/static/resources/themes/zitadel/css/zitadel.css.map index 473193707..4566893b6 100644 --- a/internal/ui/login/static/resources/themes/zitadel/css/zitadel.css.map +++ b/internal/ui/login/static/resources/themes/zitadel/css/zitadel.css.map @@ -1 +1 @@ -{"version":3,"sourceRoot":"","sources":["../../scss/styles/footer/footer.scss","../../scss/styles/header/header.scss","../../scss/styles/button/button.scss","../../scss/styles/button/button_base.scss","../../scss/styles/input/input.scss","../../scss/styles/input/input_base.scss","../../scss/styles/label/label.scss","../../scss/styles/label/label_base.scss","../../scss/styles/radio/radio_base.scss","../../scss/styles/radio/radio.scss","../../scss/styles/a/a.scss","../../scss/styles/identity_provider/identity_provider.scss","../../scss/styles/identity_provider/identity_provider_base.scss","../../scss/styles/error/error.scss","../../scss/styles/qrcode/qrcode.scss","../../scss/styles/container/container.scss","../../scss/styles/account_selection/account_selection.scss","../../scss/styles/avatar/avatar.scss","../../scss/styles/checkbox/checkbox.scss","../../scss/styles/checkbox/checkbox_base.scss","../../scss/styles/select/select.scss","../../scss/styles/select/select_base.scss","../../scss/styles/list/list_base.scss","../../scss/styles/typography/faces/ailerons_font_faces.scss","../../scss/styles/typography/faces/lato_font_faces.scss","../../scss/styles/typography/faces/roboto_font_faces.scss","../../scss/styles/typography/faces/raleway_font_faces.scss","../../scss/styles/typography/faces/pt_sans_font_faces.scss","../../scss/styles/success_label/success_label.scss","../../scss/styles/typography/typography.scss","../../scss/styles/core/core.scss","../../scss/styles/header/header_theme.scss","../../scss/styles/button/button_theme.scss","../../scss/styles/elevation/elevation.scss","../../scss/styles/input/input_theme.scss","../../scss/styles/radio/radio_theme.scss","../../scss/styles/checkbox/checkbox_theme.scss","../../scss/styles/label/label_theme.scss","../../scss/styles/footer/footer_theme.scss","../../scss/styles/a/a_theme.scss","../../scss/styles/error/error_theme.scss","../../scss/styles/qrcode/qrcode_theme.scss","../../scss/styles/container/container_theme.scss","../../scss/styles/account_selection/account_selection_theme.scss","../../scss/styles/avatar/avatar_theme.scss","../../scss/styles/select/select_theme.scss","../../scss/styles/list/list_theme.scss","../../scss/styles/identity_provider/identity_provider_theme.scss","../../scss/styles/success_label/success_label_theme.scss"],"names":[],"mappings":";AAIA;EACI;EACA;EACA;EACA,YAPY;EAQZ;EACA;EACA,SATa;;AAWb;EACI;;AAGJ;EACI;EACA;;AAGJ;EAlBJ;IAmBQ;IACA;IACA;IACA;;;;ACvBR;EACI;EACA;EACA,QALgB;EAMhB,SAPiB;EAQjB;;AAEA;EACI;EACA;EACA;;;ACXR;ECkBE;EACA;EACA;EACA;EACA;EACA;EAGA;EACA;EACA;EACA;EACA;EAGA,QAjCkB;EAkClB,WAnCqB;EAoCrB,aAlCuB;EAmCvB,SAtCmB;EAuCnB,eAnCyB;EAqCzB;;AAEA;EACE;;AAGF;EACE;;;AD1CJ;ECcE;EACA;EACA;EACA;EACA;EACA;EAGA;EACA;EACA;EACA;EACA;EAGA,QAjCkB;EAkClB,WAnCqB;EAoCrB,aAlCuB;EAmCvB,SAtCmB;EAuCnB,eAnCyB;EAqCzB;EAgBA;;AAdA;EACE;;AAGF;EACE;;;ADtCJ;EACE;EACA;EACA,OCCqB;EDArB;EACA;EACA,aCFqB;EDGrB,eCF8B;;ADI9B;EACE,aCJ0B;;;ADQ9B;EACE;EACA,SCf2B;EDgB3B,aCjB+B;;;ADoBjC;EACE;EACA,YC3B4B;;;AD+B5B;EACE;;;AEnCJ;AAAA;ECOI;EACA;EACA,sBAXsB;EAYtB;EACA;EACA;EACA;EACA,eAZsB;EAatB;EACA;EACA;EACA,cAfqB;EAgBrB,QAlBoB;EAmBpB,SArBgB;EAsBhB;EACA;EACA,QAvBe;;AAyBf;AAAA;EACI,WAtB0B;EAuB1B;;;ADrBR;ECCI;EACA;EACA,sBAXsB;EAYtB;EACA;EACA;EACA;EACA,eAZsB;EAatB;EACA;EACA;EACA,cAfqB;EAgBrB,QAlBoB;EAmBpB,SArBgB;EAsBhB;EACA;EACA,QAvBe;;AAyBf;EACI,WAtB0B;EAuB1B;;;ADjBR;EACI;;AAEA;EACI;EACA;EACA;EACA;EACA;;;AElBR;ECGI;EACA,WANkB;EAOlB;EACA,QAPe;EAQf,aAPoB;;;ACMxB;EACI;IACE;;EAGF;IACE;;EAGF;IACE;;;AChBN;EDqBI;EACA;EACA;;AAEA;EACI;;AAGJ;EACI;EACA,QA9BS;EA+BT;EACA,SA7BkB;EA8BlB;EACA;EACA;EACA;EACA;EACA,WAzCc;EA0Cd;;AAEA;EAEI;EACA;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA,OArDK;EAsDL,QAtDK;EAuDL;EACA;;AAGJ;EACI;EACA;EACA,OA7Da;EA8Db,QA9Da;EA+Db;;AAIR;EACI;EACA;EACA;EACA;EACA;;AAEA;EACI;;AAGJ;EACI;;AAGJ;EACI;;AAOA;EACI;EACA;;AAGJ;EACI;;AAKZ;AAAA;AAAA;EAGI;;;AE5GR;EACI;EACA;EACA;EACA;;AAEA;EACI;;;ACLR;ECKI;EACA,QARa;EASb;EACA;EACA;EACA;EACA,SAZc;EAad,eAXoB;EAYpB;EACA;;AAEA;EACI;EACA;;AAGJ;EACI,aAtB4B;EAuB5B;EACA;EACA;;AAIA;EACI;EACA;EACA;EACA;EACA;EACA;EACA;;;ACtCZ;EACI;EACA;EACA;;AACA;EACI;EACA;;;ACNR;EACI;EACA;EACA;EACA;;AAEA;EACI;EACA;EACA;;;ACHR;EACI,WAPsB;EAQtB;EACA;EACA,eAN0B;EAO1B;;AAEA;EAPJ;IAQQ,YAXmB;;;;AAe3B;EACI;EACA;EACA,QAnBmB;EAoBnB,SArBoB;EAsBpB;EACA;;AAGI;EACI;;AAGJ;EACI;;AAIR;EACI;EACA;EACA;EACA;;AAIA;EACI;;AAGJ;EACI;;AAIR;EACI;EACA;EACA;;AAIA;EACI;;AAGJ;EACI;;AAIR;EACI;;AAEA;EACI;EACA;;AAEJ;EACI;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;;AAGJ;EACI;;AAGA;EACI;;AAMhB;EACI;EACA;EACA;;AAGJ;EACI;EACA;;AAGJ;EACI;EACA;;AAEA;EACI;EACA;;;AAKZ;EACI;;;ACtHJ;EACI;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA;;AAEA;EACI;;AAGJ;EACI;EACA;EACA;;AAEA;EACI;EACA;EACA;;AAGJ;EACI;EACA;;AAGJ;EACI;EACA;EACA;;AAIR;EACI;;AAGJ;EACI;;;AC3CZ;EACI,QAHc;EAId,OAJc;EAKd;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;ACdJ;ECCI;EACA;EACA;EACA,WANqB;EAOrB;EACA;;AAEA;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAIJ;EACI;EACA;EACA;EACA;EACA,WA3BiB;EA4BjB;;AAEA;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AChDZ;ECCI;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACI;;;ACVJ;EACI;EACA;;AAEA;EACI;;AAIR;EACI;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;;AAKJ;EACI;EACA;EACA;EACA;EACA;EACA;;AAIR;EACI;EACA;;;ACpCR;EACI;EACA;;ACFJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AC7DJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;ACzEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AC9GJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;ACtBJ;EACI;EACA;EACA;EACA;;;ACkJA;EALE;EA9DF;EAqEE;;;AAGF;EAVE;EA9DF;EA0EE;;;AAGF;EAfE;EA9DF;EA+EE;;;AAGF;EApBE;EA9DF;EAoFE;;;AAGF;EAzBE;EA9DF;;;AA2FA;EA7BE;EA9DF;;AA8FE;EACE;;;AAIJ;EArCE;EA9DF;;;AAuGA;EAzCE;EA9DF;;;AA2GA;EA7CE;EA9DF;;;AA+GA;EAjDE;EA9DF;;;AAmHA;EArDE;EA9DF;EAqHI;;;AAGJ;EA1DE;EA9DF;EA0HE;;;AAGF;EA/DE;EA9DF;EA+HE;;;AAGF;EApEE;EA9DF;EAoIE;;;AAGF;EAzEE;EA9DF;EAyIE;;;ACrNF;EAIE;EACA;;;AAKA;EACE;;;ACNJ;EACI;EACA;EACA;;;ACIN;AAAA;AAAA;EAGE;EACA;;AAyEF;AAAA;AAAA;EACE;;AAEF;AAAA;AAAA;EACE;;AAEF;AAAA;AAAA;EACE;;AAOI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAEI;;;AApFV;AAAA;AAAA;ECwGA;;;ADjGA;EACE;;;AA4DF;EACE;;AAEF;EACE;;AAEF;EACE;;AAOI;EAEI;;AAvER;EAEE;;AAGF;EACE;;AAGF;EACE;;;AAIJ;EACE;EACA;;AAuCF;EACE;;AAEF;EACE;;AAEF;EACE;;AAOI;EAEI;;AAhBV;EACE;;AAEF;EACE;;AAEF;EACE;;AAOI;EAEI;;AAlDR;EACE;;;AAIJ;AAAA;ECiEA;;;AD5DA;EC4DA;;ADzDE;ECyDF;;ADjDE;ECiDF;;;ACnHE;AAAA;EAEE;;;AAGF;AAAA;EAEE;EACA;;AAEA;AAAA;EACE;;AAGF;AAAA;EAuBF;;AAnBE;AAAA;EAmBF;;AAdE;AAAA;EACE;;;AAIJ;AAAA;AAAA;EAGI;;;AC9BA;EACI;;AAGJ;EACI;;;AAIR;EACI;;AAEA;EACI;;AAGJ;EACI;EACA;;AAIA;EACI;;AAaJ;EACI;;;ACtCZ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;;;AAKA;EACI;EACA;;AAGJ;EACI;EACA;EACA;;;AAMJ;EACI;EACA;;AAGJ;EACI;;;AC9BR;EACE;;;ACJF;EACE;EACA;;ACLF;EACE;;AAEA;EAEI;;;ACLN;EACE;;;ACCE;EACI;;AAGJ;EACI;;AAGJ;EACI;;;ACTJ;EACI;;;AAKJ;EAEI;;;ACPR;EACI;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA;;AAEA;EAEI;;AAGJ;EACI;;AAGJ;EACI;;AAGJ;EACI;EACA;;AAGJ;EACI;;AAEA;EACI;;AAGJ;EAEI;;;ACvChB;EXqHF;;AWpGE;EACE;;AAEF;EACE;;AAEF;EACE;;AAOE;EAEI;;;AAhBR;EACE;;AAEF;EACE;;AAEF;EACE;;AAOE;EAEI;;;ACjCR;EACI;;;ACCA;EACI;;AAIA;EACI;;AAGJ;EACI;;;ACbZ;EACI;EdqHN;;AcjHM;EdiHN;;Ac7GM;EACI;EACA;;;ACXR;EACI;EACA;;;AlBTJ;EAIE;EACA;;AAKA;EACE;;;ACNJ;EACI;EACA;EACA;;ACIN;AAAA;AAAA;EAGE;EACA;;AAyEF;AAAA;AAAA;EACE;;AAEF;AAAA;AAAA;EACE;;AAEF;AAAA;AAAA;EACE;;AAOI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAEI;;AApFV;AAAA;AAAA;ECwGA;;ADjGA;EACE;;AA4DF;EACE;;AAEF;EACE;;AAEF;EACE;;AAOI;EAEI;;AAvER;EAEE;;AAGF;EACE;;AAGF;EACE;;AAIJ;EACE;EACA;;AAuCF;EACE;;AAEF;EACE;;AAEF;EACE;;AAOI;EAEI;;AAhBV;EACE;;AAEF;EACE;;AAEF;EACE;;AAOI;EAEI;;AAlDR;EACE;;AAIJ;AAAA;ECiEA;;AD5DA;EC4DA;;ADzDE;ECyDF;;ADjDE;ECiDF;;ACnHE;AAAA;EAEE;;AAGF;AAAA;EAEE;EACA;;AAEA;AAAA;EACE;;AAGF;AAAA;EAuBF;;AAnBE;AAAA;EAmBF;;AAdE;AAAA;EACE;;AAIJ;AAAA;AAAA;EAGI;;AC9BA;EACI;;AAGJ;EACI;;AAIR;EACI;;AAEA;EACI;;AAGJ;EACI;EACA;;AAIA;EACI;;AAaJ;EACI;;ACtCZ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;;AAKA;EACI;EACA;;AAGJ;EACI;EACA;EACA;;AAMJ;EACI;EACA;;AAGJ;EACI;;AC9BR;EACE;;ACJF;EACE;EACA;;ACLF;EACE;;AAEA;EAEI;;ACLN;EACE;;ACCE;EACI;;AAGJ;EACI;;AAGJ;EACI;;ACTJ;EACI;;AAKJ;EAEI;;ACPR;EACI;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA;;AAEA;EAEI;;AAGJ;EACI;;AAGJ;EACI;;AAGJ;EACI;EACA;;AAGJ;EACI;;AAEA;EACI;;AAGJ;EAEI;;ACvChB;EXqHF;;AWpGE;EACE;;AAEF;EACE;;AAEF;EACE;;AAOE;EAEI;;AAhBR;EACE;;AAEF;EACE;;AAEF;EACE;;AAOE;EAEI;;ACjCR;EACI;;ACCA;EACI;;AAIA;EACI;;AAGJ;EACI;;ACbZ;EACI;EdqHN;;AcjHM;EdiHN;;Ac7GM;EACI;EACA;;ACXR;EACI;EACA;;;AlBTJ;EAIE;EACA;;AAKA;EACE;;;ACNJ;EACI;EACA;EACA;;ACIN;AAAA;AAAA;EAGE;EACA;;AAyEF;AAAA;AAAA;EACE;;AAEF;AAAA;AAAA;EACE;;AAEF;AAAA;AAAA;EACE;;AAOI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAEI;;AApFV;AAAA;AAAA;ECwGA;;ADjGA;EACE;;AA4DF;EACE;;AAEF;EACE;;AAEF;EACE;;AAOI;EAEI;;AAvER;EAEE;;AAGF;EACE;;AAGF;EACE;;AAIJ;EACE;EACA;;AAuCF;EACE;;AAEF;EACE;;AAEF;EACE;;AAOI;EAEI;;AAhBV;EACE;;AAEF;EACE;;AAEF;EACE;;AAOI;EAEI;;AAlDR;EACE;;AAIJ;AAAA;ECiEA;;AD5DA;EC4DA;;ADzDE;ECyDF;;ADjDE;ECiDF;;ACnHE;AAAA;EAEE;;AAGF;AAAA;EAEE;EACA;;AAEA;AAAA;EACE;;AAGF;AAAA;EAuBF;;AAnBE;AAAA;EAmBF;;AAdE;AAAA;EACE;;AAIJ;AAAA;AAAA;EAGI;;AC9BA;EACI;;AAGJ;EACI;;AAIR;EACI;;AAEA;EACI;;AAGJ;EACI;EACA;;AAIA;EACI;;AAaJ;EACI;;ACtCZ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;;AAKA;EACI;EACA;;AAGJ;EACI;EACA;EACA;;AAMJ;EACI;EACA;;AAGJ;EACI;;AC9BR;EACE;;ACJF;EACE;EACA;;ACLF;EACE;;AAEA;EAEI;;ACLN;EACE;;ACCE;EACI;;AAGJ;EACI;;AAGJ;EACI;;ACTJ;EACI;;AAKJ;EAEI;;ACPR;EACI;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA;;AAEA;EAEI;;AAGJ;EACI;;AAGJ;EACI;;AAGJ;EACI;EACA;;AAGJ;EACI;;AAEA;EACI;;AAGJ;EAEI;;ACvChB;EXqHF;;AWpGE;EACE;;AAEF;EACE;;AAEF;EACE;;AAOE;EAEI;;AAhBR;EACE;;AAEF;EACE;;AAEF;EACE;;AAOE;EAEI;;ACjCR;EACI;;ACCA;EACI;;AAIA;EACI;;AAGJ;EACI;;ACbZ;EACI;EdqHN;;AcjHM;EdiHN;;Ac7GM;EACI;EACA;;ACXR;EACI;EACA","file":"zitadel.css"} \ No newline at end of file +{"version":3,"sourceRoot":"","sources":["../../scss/styles/footer/footer.scss","../../scss/styles/header/header.scss","../../scss/styles/button/button.scss","../../scss/styles/button/button_base.scss","../../scss/styles/input/input.scss","../../scss/styles/input/input_base.scss","../../scss/styles/label/label.scss","../../scss/styles/label/label_base.scss","../../scss/styles/radio/radio_base.scss","../../scss/styles/radio/radio.scss","../../scss/styles/a/a.scss","../../scss/styles/identity_provider/identity_provider.scss","../../scss/styles/identity_provider/identity_provider_base.scss","../../scss/styles/error/error.scss","../../scss/styles/qrcode/qrcode.scss","../../scss/styles/container/container.scss","../../scss/styles/account_selection/account_selection.scss","../../scss/styles/avatar/avatar.scss","../../scss/styles/checkbox/checkbox.scss","../../scss/styles/checkbox/checkbox_base.scss","../../scss/styles/select/select.scss","../../scss/styles/select/select_base.scss","../../scss/styles/list/list_base.scss","../../scss/styles/typography/faces/ailerons_font_faces.scss","../../scss/styles/typography/faces/lato_font_faces.scss","../../scss/styles/typography/faces/roboto_font_faces.scss","../../scss/styles/typography/faces/raleway_font_faces.scss","../../scss/styles/typography/faces/pt_sans_font_faces.scss","../../scss/styles/success_label/success_label.scss","../../scss/styles/typography/typography.scss","../../scss/styles/core/core.scss","../../scss/styles/header/header_theme.scss","../../scss/styles/button/button_theme.scss","../../scss/styles/elevation/elevation.scss","../../scss/styles/input/input_theme.scss","../../scss/styles/radio/radio_theme.scss","../../scss/styles/checkbox/checkbox_theme.scss","../../scss/styles/label/label_theme.scss","../../scss/styles/footer/footer_theme.scss","../../scss/styles/a/a_theme.scss","../../scss/styles/error/error_theme.scss","../../scss/styles/qrcode/qrcode_theme.scss","../../scss/styles/container/container_theme.scss","../../scss/styles/account_selection/account_selection_theme.scss","../../scss/styles/avatar/avatar_theme.scss","../../scss/styles/select/select_theme.scss","../../scss/styles/list/list_theme.scss","../../scss/styles/identity_provider/identity_provider_theme.scss","../../scss/styles/success_label/success_label_theme.scss"],"names":[],"mappings":";AAIA;EACI;EACA;EACA;EACA,YAPY;EAQZ;EACA;EACA,SATa;;AAWb;EACI;;AAGJ;EACI;EACA;;AAGJ;EAlBJ;IAmBQ;IACA;IACA;IACA;;;;ACvBR;EACI;EACA;EACA,QALgB;EAMhB,SAPiB;EAQjB;;AAEA;EACI;EACA;EACA;;;ACXR;ECkBE;EACA;EACA;EACA;EACA;EACA;EAGA;EACA;EACA;EACA;EACA;EAGA,QAjCkB;EAkClB,WAnCqB;EAoCrB,aAlCuB;EAmCvB,SAtCmB;EAuCnB,eAnCyB;EAqCzB;;AAEA;EACE;;AAGF;EACE;;;AD1CJ;ECcE;EACA;EACA;EACA;EACA;EACA;EAGA;EACA;EACA;EACA;EACA;EAGA,QAjCkB;EAkClB,WAnCqB;EAoCrB,aAlCuB;EAmCvB,SAtCmB;EAuCnB,eAnCyB;EAqCzB;EAgBA;;AAdA;EACE;;AAGF;EACE;;;ADtCJ;EACE;EACA;EACA,OCCqB;EDArB;EACA;EACA,aCFqB;EDGrB,eCF8B;;ADI9B;EACE,aCJ0B;;;ADQ9B;EACE;EACA,SCf2B;EDgB3B,aCjB+B;;;ADoBjC;EACE;EACA,YC3B4B;;;AD+B5B;EACE;;;AEnCJ;AAAA;ECOI;EACA;EACA,sBAXsB;EAYtB;EACA;EACA;EACA;EACA,eAZsB;EAatB;EACA;EACA;EACA,cAfqB;EAgBrB,QAlBoB;EAmBpB,SArBgB;EAsBhB;EACA;EACA,QAvBe;;AAyBf;AAAA;EACI,WAtB0B;EAuB1B;;;ADrBR;ECCI;EACA;EACA,sBAXsB;EAYtB;EACA;EACA;EACA;EACA,eAZsB;EAatB;EACA;EACA;EACA,cAfqB;EAgBrB,QAlBoB;EAmBpB,SArBgB;EAsBhB;EACA;EACA,QAvBe;;AAyBf;EACI,WAtB0B;EAuB1B;;;ADjBR;EACI;;AAEA;EACI;EACA;EACA;EACA;EACA;;;AElBR;ECGI;EACA,WANkB;EAOlB;EACA,QAPe;EAQf,aAPoB;;;ACMxB;EACI;IACE;;EAGF;IACE;;EAGF;IACE;;;AChBN;EDqBI;EACA;EACA;;AAEA;EACI;;AAGJ;EACI;EACA,QA9BS;EA+BT;EACA,SA7BkB;EA8BlB;EACA;EACA;EACA;EACA;EACA,WAzCc;EA0Cd;;AAEA;EAEI;EACA;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA,OArDK;EAsDL,QAtDK;EAuDL;EACA;;AAGJ;EACI;EACA;EACA,OA7Da;EA8Db,QA9Da;EA+Db;;AAIR;EACI;EACA;EACA;EACA;EACA;;AAEA;EACI;;AAGJ;EACI;;AAGJ;EACI;;AAOA;EACI;EACA;;AAGJ;EACI;;AAKZ;AAAA;AAAA;EAGI;;;AE5GR;EACI;EACA;EACA;EACA;;AAEA;EACI;;;ACLR;ECKI;EACA,QARa;EASb;EACA;EACA;EACA;EACA,SAZc;EAad,eAXoB;EAYpB;EACA;;AAEA;EACI;EACA;;AAGJ;EACI,aAtB4B;EAuB5B;EACA;EACA;;AAIA;EACI;EACA;EACA;EACA;EACA;EACA;EACA;;;ACtCZ;EACI;EACA;EACA;;AACA;EACI;EACA;;;ACNR;EACI;EACA;EACA;EACA;;AAEA;EACI;EACA;EACA;;;ACHR;EACI,WAPsB;EAQtB;EACA;EACA,eAN0B;EAO1B;;AAEA;EAPJ;IAQQ,YAXmB;;;;AAe3B;EACI;EACA;EACA,QAnBmB;EAoBnB,SArBoB;EAsBpB;EACA;;AAGI;EACI;;AAGJ;EACI;;AAIR;EACI;EACA;EACA;EACA;;AAIA;EACI;;AAGJ;EACI;;AAIR;EACI;EACA;EACA;;AAIA;EACI;;AAGJ;EACI;;AAIR;EACI;;AAEA;EACI;EACA;;AAEJ;EACI;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;;AAGJ;EACI;;AAGA;EACI;;AAMhB;EACI;EACA;EACA;;AAGJ;EACI;EACA;;AAGJ;EACI;EACA;;AAEA;EACI;EACA;;;AAKZ;EACI;;;ACtHJ;EACI;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA;;AAEA;EACI;;AAGJ;EACI;EACA;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;;AAIR;EACI;;AAGJ;EACI;;;AChDZ;EACI,QAHc;EAId,OAJc;EAKd;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;ACdJ;ECCI;EACA;EACA;EACA,WANqB;EAOrB;EACA;;AAEA;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAIJ;EACI;EACA;EACA;EACA;EACA,WA3BiB;EA4BjB;;AAEA;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AChDZ;ECCI;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACI;;;ACVJ;EACI;EACA;;AAEA;EACI;;AAIR;EACI;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;;AAKJ;EACI;EACA;EACA;EACA;EACA;EACA;;AAIR;EACI;EACA;;;ACpCR;EACI;EACA;;ACFJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AC7DJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;ACzEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AC9GJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;ACtBJ;EACI;EACA;EACA;EACA;;;ACkJA;EALE;EA9DF;EAqEE;;;AAGF;EAVE;EA9DF;EA0EE;;;AAGF;EAfE;EA9DF;EA+EE;;;AAGF;EApBE;EA9DF;EAoFE;;;AAGF;EAzBE;EA9DF;;;AA2FA;EA7BE;EA9DF;;AA8FE;EACE;;;AAIJ;EArCE;EA9DF;;;AAuGA;EAzCE;EA9DF;;;AA2GA;EA7CE;EA9DF;;;AA+GA;EAjDE;EA9DF;;;AAmHA;EArDE;EA9DF;EAqHI;;;AAGJ;EA1DE;EA9DF;EA0HE;;;AAGF;EA/DE;EA9DF;EA+HE;;;AAGF;EApEE;EA9DF;EAoIE;;;AAGF;EAzEE;EA9DF;EAyIE;;;ACrNF;EAIE;EACA;;;AAKA;EACE;;;ACNJ;EACI;EACA;EACA;;;ACIN;AAAA;AAAA;EAGE;EACA;;AAyEF;AAAA;AAAA;EACE;;AAEF;AAAA;AAAA;EACE;;AAEF;AAAA;AAAA;EACE;;AAOI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAEI;;;AApFV;AAAA;AAAA;ECwGA;;;ADjGA;EACE;;;AA4DF;EACE;;AAEF;EACE;;AAEF;EACE;;AAOI;EAEI;;AAvER;EAEE;;AAGF;EACE;;AAGF;EACE;;;AAIJ;EACE;EACA;;AAuCF;EACE;;AAEF;EACE;;AAEF;EACE;;AAOI;EAEI;;AAhBV;EACE;;AAEF;EACE;;AAEF;EACE;;AAOI;EAEI;;AAlDR;EACE;;;AAIJ;AAAA;ECiEA;;;AD5DA;EC4DA;;ADzDE;ECyDF;;ADjDE;ECiDF;;;ACnHE;AAAA;EAEE;;;AAGF;AAAA;EAEE;EACA;;AAEA;AAAA;EACE;;AAGF;AAAA;EAuBF;;AAnBE;AAAA;EAmBF;;AAdE;AAAA;EACE;;;AAIJ;AAAA;AAAA;EAGI;;;AC9BA;EACI;;AAGJ;EACI;;;AAIR;EACI;;AAEA;EACI;;AAGJ;EACI;EACA;;AAIA;EACI;;AAaJ;EACI;;;ACtCZ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;;;AAKA;EACI;EACA;;AAGJ;EACI;EACA;EACA;;;AAMJ;EACI;EACA;;AAGJ;EACI;;;AC9BR;EACE;;;ACJF;EACE;EACA;;ACLF;EACE;;AAEA;EAEI;;;ACLN;EACE;;;ACCE;EACI;;AAGJ;EACI;;AAGJ;EACI;;;ACTJ;EACI;;;AAKJ;EAEI;;;ACPR;EACI;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA;;AAEA;EAEI;;AAGJ;EACI;;AAGJ;EACI;;AAGJ;EACI;EACA;;AAGJ;EACI;;AAEA;EACI;;AAGJ;EAEI;;;ACvChB;EXqHF;;AWpGE;EACE;;AAEF;EACE;;AAEF;EACE;;AAOE;EAEI;;;AAhBR;EACE;;AAEF;EACE;;AAEF;EACE;;AAOE;EAEI;;;ACjCR;EACI;;;ACCA;EACI;;AAIA;EACI;;AAGJ;EACI;;;ACbZ;EACI;EdqHN;;AcjHM;EdiHN;;Ac7GM;EACI;EACA;;;ACXR;EACI;EACA;;;AlBTJ;EAIE;EACA;;AAKA;EACE;;;ACNJ;EACI;EACA;EACA;;ACIN;AAAA;AAAA;EAGE;EACA;;AAyEF;AAAA;AAAA;EACE;;AAEF;AAAA;AAAA;EACE;;AAEF;AAAA;AAAA;EACE;;AAOI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAEI;;AApFV;AAAA;AAAA;ECwGA;;ADjGA;EACE;;AA4DF;EACE;;AAEF;EACE;;AAEF;EACE;;AAOI;EAEI;;AAvER;EAEE;;AAGF;EACE;;AAGF;EACE;;AAIJ;EACE;EACA;;AAuCF;EACE;;AAEF;EACE;;AAEF;EACE;;AAOI;EAEI;;AAhBV;EACE;;AAEF;EACE;;AAEF;EACE;;AAOI;EAEI;;AAlDR;EACE;;AAIJ;AAAA;ECiEA;;AD5DA;EC4DA;;ADzDE;ECyDF;;ADjDE;ECiDF;;ACnHE;AAAA;EAEE;;AAGF;AAAA;EAEE;EACA;;AAEA;AAAA;EACE;;AAGF;AAAA;EAuBF;;AAnBE;AAAA;EAmBF;;AAdE;AAAA;EACE;;AAIJ;AAAA;AAAA;EAGI;;AC9BA;EACI;;AAGJ;EACI;;AAIR;EACI;;AAEA;EACI;;AAGJ;EACI;EACA;;AAIA;EACI;;AAaJ;EACI;;ACtCZ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;;AAKA;EACI;EACA;;AAGJ;EACI;EACA;EACA;;AAMJ;EACI;EACA;;AAGJ;EACI;;AC9BR;EACE;;ACJF;EACE;EACA;;ACLF;EACE;;AAEA;EAEI;;ACLN;EACE;;ACCE;EACI;;AAGJ;EACI;;AAGJ;EACI;;ACTJ;EACI;;AAKJ;EAEI;;ACPR;EACI;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA;;AAEA;EAEI;;AAGJ;EACI;;AAGJ;EACI;;AAGJ;EACI;EACA;;AAGJ;EACI;;AAEA;EACI;;AAGJ;EAEI;;ACvChB;EXqHF;;AWpGE;EACE;;AAEF;EACE;;AAEF;EACE;;AAOE;EAEI;;AAhBR;EACE;;AAEF;EACE;;AAEF;EACE;;AAOE;EAEI;;ACjCR;EACI;;ACCA;EACI;;AAIA;EACI;;AAGJ;EACI;;ACbZ;EACI;EdqHN;;AcjHM;EdiHN;;Ac7GM;EACI;EACA;;ACXR;EACI;EACA;;;AlBTJ;EAIE;EACA;;AAKA;EACE;;;ACNJ;EACI;EACA;EACA;;ACIN;AAAA;AAAA;EAGE;EACA;;AAyEF;AAAA;AAAA;EACE;;AAEF;AAAA;AAAA;EACE;;AAEF;AAAA;AAAA;EACE;;AAOI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAEI;;AApFV;AAAA;AAAA;ECwGA;;ADjGA;EACE;;AA4DF;EACE;;AAEF;EACE;;AAEF;EACE;;AAOI;EAEI;;AAvER;EAEE;;AAGF;EACE;;AAGF;EACE;;AAIJ;EACE;EACA;;AAuCF;EACE;;AAEF;EACE;;AAEF;EACE;;AAOI;EAEI;;AAhBV;EACE;;AAEF;EACE;;AAEF;EACE;;AAOI;EAEI;;AAlDR;EACE;;AAIJ;AAAA;ECiEA;;AD5DA;EC4DA;;ADzDE;ECyDF;;ADjDE;ECiDF;;ACnHE;AAAA;EAEE;;AAGF;AAAA;EAEE;EACA;;AAEA;AAAA;EACE;;AAGF;AAAA;EAuBF;;AAnBE;AAAA;EAmBF;;AAdE;AAAA;EACE;;AAIJ;AAAA;AAAA;EAGI;;AC9BA;EACI;;AAGJ;EACI;;AAIR;EACI;;AAEA;EACI;;AAGJ;EACI;EACA;;AAIA;EACI;;AAaJ;EACI;;ACtCZ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;;AAKA;EACI;EACA;;AAGJ;EACI;EACA;EACA;;AAMJ;EACI;EACA;;AAGJ;EACI;;AC9BR;EACE;;ACJF;EACE;EACA;;ACLF;EACE;;AAEA;EAEI;;ACLN;EACE;;ACCE;EACI;;AAGJ;EACI;;AAGJ;EACI;;ACTJ;EACI;;AAKJ;EAEI;;ACPR;EACI;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA;;AAEA;EAEI;;AAGJ;EACI;;AAGJ;EACI;;AAGJ;EACI;EACA;;AAGJ;EACI;;AAEA;EACI;;AAGJ;EAEI;;ACvChB;EXqHF;;AWpGE;EACE;;AAEF;EACE;;AAEF;EACE;;AAOE;EAEI;;AAhBR;EACE;;AAEF;EACE;;AAEF;EACE;;AAOE;EAEI;;ACjCR;EACI;;ACCA;EACI;;AAIA;EACI;;AAGJ;EACI;;ACbZ;EACI;EdqHN;;AcjHM;EdiHN;;Ac7GM;EACI;EACA;;ACXR;EACI;EACA","file":"zitadel.css"} \ No newline at end of file diff --git a/internal/ui/login/static/templates/link_users_done.html b/internal/ui/login/static/templates/link_users_done.html index af1922b16..5b5a76b05 100644 --- a/internal/ui/login/static/templates/link_users_done.html +++ b/internal/ui/login/static/templates/link_users_done.html @@ -17,7 +17,7 @@ {{t "Actions.Cancel"}} - + diff --git a/internal/user/model/machine_key.go b/internal/user/model/machine_key.go deleted file mode 100644 index c38aa1b63..000000000 --- a/internal/user/model/machine_key.go +++ /dev/null @@ -1,54 +0,0 @@ -package model - -import ( - "time" - - "github.com/caos/zitadel/internal/model" -) - -type MachineKeyView struct { - ID string - UserID string - Type MachineKeyType - Sequence uint64 - CreationDate time.Time - ExpirationDate time.Time - PublicKey []byte -} - -type MachineKeySearchRequest struct { - Offset uint64 - Limit uint64 - SortingColumn MachineKeySearchKey - Asc bool - Queries []*MachineKeySearchQuery -} - -type MachineKeySearchKey int32 - -const ( - MachineKeyKeyUnspecified MachineKeySearchKey = iota - MachineKeyKeyID - MachineKeyKeyUserID -) - -type MachineKeySearchQuery struct { - Key MachineKeySearchKey - Method model.SearchMethod - Value interface{} -} - -type MachineKeySearchResponse struct { - Offset uint64 - Limit uint64 - TotalResult uint64 - Result []*MachineKeyView - Sequence uint64 - Timestamp time.Time -} - -func (r *MachineKeySearchRequest) EnsureLimit(limit uint64) { - if r.Limit == 0 || r.Limit > limit { - r.Limit = limit - } -} diff --git a/internal/user/model/user_machine.go b/internal/user/model/user_machine.go index d635f8150..1f1c06a69 100644 --- a/internal/user/model/user_machine.go +++ b/internal/user/model/user_machine.go @@ -4,6 +4,7 @@ import ( "time" "github.com/caos/zitadel/internal/eventstore/models" + key_model "github.com/caos/zitadel/internal/key/model" ) type Machine struct { @@ -21,14 +22,7 @@ type MachineKey struct { models.ObjectRoot KeyID string - Type MachineKeyType + Type key_model.AuthNKeyType ExpirationDate time.Time PrivateKey []byte } - -type MachineKeyType int32 - -const ( - MachineKeyTypeNONE = iota - MachineKeyTypeJSON -) diff --git a/internal/user/repository/eventsourcing/eventstore.go b/internal/user/repository/eventsourcing/eventstore.go index 236964256..7beeef6b1 100644 --- a/internal/user/repository/eventsourcing/eventstore.go +++ b/internal/user/repository/eventsourcing/eventstore.go @@ -20,6 +20,7 @@ import ( es_sdk "github.com/caos/zitadel/internal/eventstore/sdk" iam_model "github.com/caos/zitadel/internal/iam/model" "github.com/caos/zitadel/internal/id" + key_model "github.com/caos/zitadel/internal/key/model" global_model "github.com/caos/zitadel/internal/model" "github.com/caos/zitadel/internal/telemetry/tracing" usr_model "github.com/caos/zitadel/internal/user/model" @@ -27,11 +28,6 @@ import ( webauthn_helper "github.com/caos/zitadel/internal/webauthn" ) -const ( - yearLayout = "2006-01-02" - defaultExpirationDate = "9999-01-01" -) - type UserEventstore struct { es_int.Eventstore userCache *UserCache @@ -1638,7 +1634,7 @@ func (es *UserEventstore) AddMachineKey(ctx context.Context, key *usr_model.Mach } if key.ExpirationDate.IsZero() { - key.ExpirationDate, err = time.Parse(yearLayout, defaultExpirationDate) + key.ExpirationDate, err = key_model.DefaultExpiration() if err != nil { logging.Log("EVENT-vzibi").WithError(err).Warn("unable to set default date") return nil, errors.ThrowInternal(err, "EVENT-j68fg", "Errors.Internal") diff --git a/internal/user/repository/eventsourcing/model/user_machine.go b/internal/user/repository/eventsourcing/model/user_machine.go index f73c75c5f..a82fad1c1 100644 --- a/internal/user/repository/eventsourcing/model/user_machine.go +++ b/internal/user/repository/eventsourcing/model/user_machine.go @@ -9,6 +9,7 @@ import ( "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore/models" es_models "github.com/caos/zitadel/internal/eventstore/models" + key_model "github.com/caos/zitadel/internal/key/model" "github.com/caos/zitadel/internal/user/model" ) @@ -115,7 +116,7 @@ func MachineKeyToModel(machine *MachineKey) *model.MachineKey { ExpirationDate: machine.ExpirationDate, KeyID: machine.KeyID, PrivateKey: machine.privateKey, - Type: model.MachineKeyType(machine.Type), + Type: key_model.AuthNKeyType(machine.Type), } } diff --git a/internal/user/repository/view/machine_key_view.go b/internal/user/repository/view/machine_key_view.go deleted file mode 100644 index 479859eab..000000000 --- a/internal/user/repository/view/machine_key_view.go +++ /dev/null @@ -1,77 +0,0 @@ -package view - -import ( - caos_errs "github.com/caos/zitadel/internal/errors" - global_model "github.com/caos/zitadel/internal/model" - usr_model "github.com/caos/zitadel/internal/user/model" - "github.com/caos/zitadel/internal/user/repository/view/model" - "github.com/caos/zitadel/internal/view/repository" - "github.com/jinzhu/gorm" -) - -func MachineKeyByIDs(db *gorm.DB, table, userID, keyID string) (*model.MachineKeyView, error) { - key := new(model.MachineKeyView) - query := repository.PrepareGetByQuery(table, - model.MachineKeySearchQuery{Key: usr_model.MachineKeyKeyUserID, Method: global_model.SearchMethodEquals, Value: userID}, - model.MachineKeySearchQuery{Key: usr_model.MachineKeyKeyID, Method: global_model.SearchMethodEquals, Value: keyID}, - ) - err := query(db, key) - if caos_errs.IsNotFound(err) { - return nil, caos_errs.ThrowNotFound(nil, "VIEW-3Dk9s", "Errors.User.KeyNotFound") - } - return key, err -} - -func SearchMachineKeys(db *gorm.DB, table string, req *usr_model.MachineKeySearchRequest) ([]*model.MachineKeyView, uint64, error) { - members := make([]*model.MachineKeyView, 0) - query := repository.PrepareSearchQuery(table, model.MachineKeySearchRequest{Limit: req.Limit, Offset: req.Offset, Queries: req.Queries}) - count, err := query(db, &members) - if err != nil { - return nil, 0, err - } - return members, count, nil -} - -func MachineKeysByUserID(db *gorm.DB, table string, userID string) ([]*model.MachineKeyView, error) { - keys := make([]*model.MachineKeyView, 0) - queries := []*usr_model.MachineKeySearchQuery{ - { - Key: usr_model.MachineKeyKeyUserID, - Value: userID, - Method: global_model.SearchMethodEquals, - }, - } - query := repository.PrepareSearchQuery(table, model.MachineKeySearchRequest{Queries: queries}) - _, err := query(db, &keys) - if err != nil { - return nil, err - } - return keys, nil -} - -func MachineKeyByID(db *gorm.DB, table string, keyID string) (*model.MachineKeyView, error) { - key := new(model.MachineKeyView) - query := repository.PrepareGetByQuery(table, - model.MachineKeySearchQuery{Key: usr_model.MachineKeyKeyID, Method: global_model.SearchMethodEquals, Value: keyID}, - ) - err := query(db, key) - if caos_errs.IsNotFound(err) { - return nil, caos_errs.ThrowNotFound(nil, "VIEW-BjN6x", "Errors.User.KeyNotFound") - } - return key, err -} - -func PutMachineKey(db *gorm.DB, table string, role *model.MachineKeyView) error { - save := repository.PrepareSave(table) - return save(db, role) -} - -func DeleteMachineKey(db *gorm.DB, table, keyID string) error { - delete := repository.PrepareDeleteByKey(table, model.MachineKeySearchKey(usr_model.MachineKeyKeyID), keyID) - return delete(db) -} - -func DeleteMachineKeysByUserID(db *gorm.DB, table, userID string) error { - delete := repository.PrepareDeleteByKey(table, model.MachineKeySearchKey(usr_model.MachineKeyKeyUserID), userID) - return delete(db) -} diff --git a/internal/user/repository/view/model/machine_key.go b/internal/user/repository/view/model/machine_key.go deleted file mode 100644 index ddd921d59..000000000 --- a/internal/user/repository/view/model/machine_key.go +++ /dev/null @@ -1,84 +0,0 @@ -package model - -import ( - "encoding/json" - "time" - - "github.com/caos/logging" - - caos_errs "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/models" - "github.com/caos/zitadel/internal/user/model" - es_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model" -) - -const ( - MachineKeyKeyID = "id" - MachineKeyKeyUserID = "user_id" -) - -type MachineKeyView struct { - ID string `json:"keyId" gorm:"column:id;primary_key"` - UserID string `json:"-" gorm:"column:user_id;primary_key"` - Type int32 `json:"type" gorm:"column:machine_type"` - ExpirationDate time.Time `json:"expirationDate" gorm:"column:expiration_date"` - Sequence uint64 `json:"-" gorm:"column:sequence"` - - CreationDate time.Time `json:"-" gorm:"column:creation_date"` - - PublicKey []byte `json:"publicKey" gorm:"column:public_key"` -} - -func MachineKeyViewFromModel(key *model.MachineKeyView) *MachineKeyView { - return &MachineKeyView{ - ID: key.ID, - UserID: key.UserID, - Type: int32(key.Type), - ExpirationDate: key.ExpirationDate, - Sequence: key.Sequence, - CreationDate: key.CreationDate, - } -} - -func MachineKeyToModel(key *MachineKeyView) *model.MachineKeyView { - return &model.MachineKeyView{ - ID: key.ID, - UserID: key.UserID, - Type: model.MachineKeyType(key.Type), - ExpirationDate: key.ExpirationDate, - Sequence: key.Sequence, - CreationDate: key.CreationDate, - PublicKey: key.PublicKey, - } -} - -func MachineKeysToModel(keys []*MachineKeyView) []*model.MachineKeyView { - result := make([]*model.MachineKeyView, len(keys)) - for i, key := range keys { - result[i] = MachineKeyToModel(key) - } - return result -} - -func (k *MachineKeyView) AppendEvent(event *models.Event) (err error) { - k.Sequence = event.Sequence - switch event.Type { - case es_model.MachineKeyAdded: - k.setRootData(event) - k.CreationDate = event.CreationDate - err = k.SetData(event) - } - return err -} - -func (k *MachineKeyView) setRootData(event *models.Event) { - k.UserID = event.AggregateID -} - -func (r *MachineKeyView) SetData(event *models.Event) error { - if err := json.Unmarshal(event.Data, r); err != nil { - logging.Log("EVEN-Sj90d").WithError(err).Error("could not unmarshal event data") - return caos_errs.ThrowInternal(err, "MODEL-lub6s", "Could not unmarshal data") - } - return nil -} diff --git a/internal/user/repository/view/model/machine_key_query.go b/internal/user/repository/view/model/machine_key_query.go deleted file mode 100644 index c5a876ce5..000000000 --- a/internal/user/repository/view/model/machine_key_query.go +++ /dev/null @@ -1,61 +0,0 @@ -package model - -import ( - global_model "github.com/caos/zitadel/internal/model" - usr_model "github.com/caos/zitadel/internal/user/model" - "github.com/caos/zitadel/internal/view/repository" -) - -type MachineKeySearchRequest usr_model.MachineKeySearchRequest -type MachineKeySearchQuery usr_model.MachineKeySearchQuery -type MachineKeySearchKey usr_model.MachineKeySearchKey - -func (req MachineKeySearchRequest) GetLimit() uint64 { - return req.Limit -} - -func (req MachineKeySearchRequest) GetOffset() uint64 { - return req.Offset -} - -func (req MachineKeySearchRequest) GetSortingColumn() repository.ColumnKey { - if req.SortingColumn == usr_model.MachineKeyKeyUnspecified { - return nil - } - return MachineKeySearchKey(req.SortingColumn) -} - -func (req MachineKeySearchRequest) GetAsc() bool { - return req.Asc -} - -func (req MachineKeySearchRequest) GetQueries() []repository.SearchQuery { - result := make([]repository.SearchQuery, len(req.Queries)) - for i, q := range req.Queries { - result[i] = MachineKeySearchQuery{Key: q.Key, Value: q.Value, Method: q.Method} - } - return result -} - -func (req MachineKeySearchQuery) GetKey() repository.ColumnKey { - return MachineKeySearchKey(req.Key) -} - -func (req MachineKeySearchQuery) GetMethod() global_model.SearchMethod { - return req.Method -} - -func (req MachineKeySearchQuery) GetValue() interface{} { - return req.Value -} - -func (key MachineKeySearchKey) ToColumnName() string { - switch usr_model.MachineKeySearchKey(key) { - case usr_model.MachineKeyKeyID: - return MachineKeyKeyID - case usr_model.MachineKeyKeyUserID: - return MachineKeyKeyUserID - default: - return "" - } -} diff --git a/internal/user/repository/view/model/token.go b/internal/user/repository/view/model/token.go index eb20cf76c..24906d2a5 100644 --- a/internal/user/repository/view/model/token.go +++ b/internal/user/repository/view/model/token.go @@ -5,6 +5,7 @@ import ( "time" "github.com/caos/logging" + caos_errs "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore/models" es_models "github.com/caos/zitadel/internal/eventstore/models" diff --git a/internal/v2/command/setup_step11.go b/internal/v2/command/setup_step11.go index ec47cc131..9b70533cc 100644 --- a/internal/v2/command/setup_step11.go +++ b/internal/v2/command/setup_step11.go @@ -22,12 +22,16 @@ func (s *Step11) execute(ctx context.Context, commandSide *CommandSide) error { func (r *CommandSide) SetupStep11(ctx context.Context, step *Step11) error { fn := func(iam *IAMWriteModel) (*iam_repo.Aggregate, error) { iamAgg := IAMAggregateFromWriteModel(&iam.WriteModel) - uniqueConstraints := NewUniqueConstraintReadModel(ctx, r) - err := r.eventstore.FilterToQueryReducer(ctx, uniqueConstraints) - if err != nil { - return nil, err + var uniqueContraintMigrations []*domain.UniqueConstraintMigration + if step.MigrateV1EventstoreToV2 { + uniqueConstraints := NewUniqueConstraintReadModel(ctx, r) + err := r.eventstore.FilterToQueryReducer(ctx, uniqueConstraints) + if err != nil { + return nil, err + } + uniqueContraintMigrations = uniqueConstraints.UniqueConstraints } - iamAgg.PushEvents(iam_repo.NewMigrateUniqueConstraintEvent(ctx, uniqueConstraints.UniqueConstraints)) + iamAgg.PushEvents(iam_repo.NewMigrateUniqueConstraintEvent(ctx, uniqueContraintMigrations)) logging.Log("SETUP-M9fsd").Info("migrate v1 eventstore to v2") return iamAgg, nil } diff --git a/internal/v2/command/unique_constraints_model.go b/internal/v2/command/unique_constraints_model.go index c61f8f4d8..0c5bf3a9e 100644 --- a/internal/v2/command/unique_constraints_model.go +++ b/internal/v2/command/unique_constraints_model.go @@ -45,7 +45,7 @@ func (rm *UniqueConstraintReadModel) Reduce() error { rm.addUniqueConstraint(e.AggregateID(), e.AggregateID(), org.NewAddOrgNameUniqueConstraint(e.Name)) case *org.OrgChangedEvent: rm.changeUniqueConstraint(e.AggregateID(), e.AggregateID(), org.NewAddOrgNameUniqueConstraint(e.Name)) - case *org.DomainVerificationAddedEvent: + case *org.DomainVerifiedEvent: rm.addUniqueConstraint(e.AggregateID(), e.AggregateID(), org.NewAddOrgNameUniqueConstraint(e.Domain)) case *org.DomainRemovedEvent: rm.removeUniqueConstraint(e.AggregateID(), e.AggregateID(), org.UniqueOrgDomain) @@ -158,9 +158,7 @@ func (rm *UniqueConstraintReadModel) Reduce() error { } func (rm *UniqueConstraintReadModel) Query() *eventstore.SearchQueryBuilder { - return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent). - AggregateIDs(rm.AggregateID). - ResourceOwner(rm.ResourceOwner). + return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType, org.AggregateType, project.AggregateType, user.AggregateType, usergrant.AggregateType). EventTypes( org.OrgAddedEventType, org.OrgChangedEventType, diff --git a/internal/v2/domain/application_oidc.go b/internal/v2/domain/application_oidc.go index b652b8f2b..b5c6cf54b 100644 --- a/internal/v2/domain/application_oidc.go +++ b/internal/v2/domain/application_oidc.go @@ -90,6 +90,7 @@ const ( OIDCAuthMethodTypeBasic OIDCAuthMethodType = iota OIDCAuthMethodTypePost OIDCAuthMethodTypeNone + OIDCAuthMethodTypePrivateKeyJWT ) type Compliance struct { diff --git a/migrations/cockroach/V1.29__user_memberships.sql b/migrations/cockroach/V1.29__user_memberships.sql new file mode 100644 index 000000000..30d4259ce --- /dev/null +++ b/migrations/cockroach/V1.29__user_memberships.sql @@ -0,0 +1,18 @@ +CREATE TABLE authz.user_memberships ( + user_id TEXT, + member_type SMALLINT, + aggregate_id TEXT, + object_id TEXT, + + roles TEXT ARRAY, + display_name TEXT, + resource_owner TEXT, + resource_owner_name TEXT, + creation_date TIMESTAMPTZ, + change_date TIMESTAMPTZ, + sequence BIGINT, + + PRIMARY KEY (user_id, member_type, aggregate_id, object_id) +); + +ALTER TABLE authz.user_memberships OWNER TO admin; \ No newline at end of file diff --git a/migrations/cockroach/V1.30__user_memberships.sql b/migrations/cockroach/V1.30__user_memberships.sql new file mode 100644 index 000000000..82146e0f1 --- /dev/null +++ b/migrations/cockroach/V1.30__user_memberships.sql @@ -0,0 +1,47 @@ +BEGIN; + +TRUNCATE TABLE authz.user_memberships; + +INSERT INTO authz.user_memberships ( + user_id, + member_type, + aggregate_id, + object_id, + roles, + display_name, + resource_owner, + resource_owner_name, + creation_date, + change_date, + sequence +) +SELECT + user_id, + member_type, + aggregate_id, + object_id, + roles, + display_name, + resource_owner, + resource_owner_name, + creation_date, + change_date, + sequence +FROM auth.user_memberships; + +UPSERT INTO authz.current_sequences ( + view_name, + event_timestamp, + current_sequence, + last_successful_spooler_run, + aggregate_type + ) +SELECT 'authz.user_memberships', + event_timestamp, + current_sequence, + last_successful_spooler_run, + aggregate_type +FROM auth.current_sequences +WHERE view_name = 'auth.user_memberships'; + +COMMIT; \ No newline at end of file diff --git a/migrations/cockroach/V1.31__auth_keys.sql b/migrations/cockroach/V1.31__auth_keys.sql new file mode 100644 index 000000000..5c091d1b5 --- /dev/null +++ b/migrations/cockroach/V1.31__auth_keys.sql @@ -0,0 +1,92 @@ +CREATE TABLE auth.authn_keys +( + key_id TEXT, + object_id TEXT, + object_type SMALLINT, + auth_identifier TEXT, + + key_type SMALLINT, + sequence BIGINT, + expiration_date TIMESTAMPTZ, + creation_date TIMESTAMPTZ, + public_key BYTES, + state SMALLINT, + + PRIMARY KEY (key_id, object_id, object_type, auth_identifier) +); + +INSERT INTO auth.authn_keys ( + key_id, + object_id, + object_type, + auth_identifier, + key_type, + sequence, + expiration_date, + creation_date, + public_key, + state + ) + SELECT + id, + user_id, + 0, + user_id, + machine_type, + sequence, + expiration_date, + creation_date, + public_key, + 0 + FROM auth.machine_keys; + +CREATE TABLE management.authn_keys +( + key_id TEXT, + object_id TEXT, + object_type SMALLINT, + auth_identifier TEXT, + + key_type SMALLINT, + sequence BIGINT, + expiration_date TIMESTAMPTZ, + creation_date TIMESTAMPTZ, + public_key BYTES, + state SMALLINT, + + PRIMARY KEY (key_id, object_id, object_type, auth_identifier) +); + +INSERT INTO management.authn_keys ( + key_id, + object_id, + object_type, + auth_identifier, + key_type, + sequence, + expiration_date, + creation_date, + public_key, + state +) +SELECT + id, + user_id, + 0, + user_id, + machine_type, + sequence, + expiration_date, + creation_date, + public_key, + 0 +FROM management.machine_keys; + +INSERT INTO auth.current_sequences (view_name, event_timestamp, current_sequence, last_successful_spooler_run, aggregate_type) + SELECT 'auth.authn_keys', event_timestamp, current_sequence, last_successful_spooler_run, aggregate_type FROM auth.current_sequences WHERE view_name = 'auth.machine_keys'; + +INSERT INTO management.current_sequences (view_name, event_timestamp, current_sequence, last_successful_spooler_run, aggregate_type) + SELECT 'management.authn_keys', event_timestamp, current_sequence, last_successful_spooler_run, aggregate_type FROM management.current_sequences WHERE view_name = 'management.machine_keys'; + +ALTER TABLE auth.authn_keys OWNER TO admin; +ALTER TABLE management.authn_keys OWNER TO admin; diff --git a/migrations/cockroach/V1.29__unique_tables.sql b/migrations/cockroach/V1.32__unique_tables.sql similarity index 100% rename from migrations/cockroach/V1.29__unique_tables.sql rename to migrations/cockroach/V1.32__unique_tables.sql diff --git a/migrations/cockroach/V1.30__policies.sql b/migrations/cockroach/V1.33__policies.sql similarity index 100% rename from migrations/cockroach/V1.30__policies.sql rename to migrations/cockroach/V1.33__policies.sql diff --git a/pkg/grpc/auth/mock/auth.proto.mock.go b/pkg/grpc/auth/mock/auth.proto.mock.go index 97405e6fd..6f6dd6136 100644 --- a/pkg/grpc/auth/mock/auth.proto.mock.go +++ b/pkg/grpc/auth/mock/auth.proto.mock.go @@ -636,6 +636,26 @@ func (mr *MockAuthServiceClientMockRecorder) SearchMyUserGrant(arg0, arg1 interf return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SearchMyUserGrant", reflect.TypeOf((*MockAuthServiceClient)(nil).SearchMyUserGrant), varargs...) } +// SearchMyUserMemberships mocks base method +func (m *MockAuthServiceClient) SearchMyUserMemberships(arg0 context.Context, arg1 *auth.UserMembershipSearchRequest, arg2 ...grpc.CallOption) (*auth.UserMembershipSearchResponse, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "SearchMyUserMemberships", varargs...) + ret0, _ := ret[0].(*auth.UserMembershipSearchResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// SearchMyUserMemberships indicates an expected call of SearchMyUserMemberships +func (mr *MockAuthServiceClientMockRecorder) SearchMyUserMemberships(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SearchMyUserMemberships", reflect.TypeOf((*MockAuthServiceClient)(nil).SearchMyUserMemberships), varargs...) +} + // UpdateMyUserAddress mocks base method func (m *MockAuthServiceClient) UpdateMyUserAddress(arg0 context.Context, arg1 *auth.UpdateUserAddressRequest, arg2 ...grpc.CallOption) (*auth.UserAddress, error) { m.ctrl.T.Helper() diff --git a/pkg/grpc/auth/proto/auth.proto b/pkg/grpc/auth/proto/auth.proto index 645a03af6..bb5ca291a 100644 --- a/pkg/grpc/auth/proto/auth.proto +++ b/pkg/grpc/auth/proto/auth.proto @@ -418,6 +418,17 @@ service AuthService { permission: "authenticated" }; } + + rpc SearchMyUserMemberships(UserMembershipSearchRequest) returns (UserMembershipSearchResponse) { + option (google.api.http) = { + post: "/users/me/memberships/_search" + body: "*" + }; + + option (caos.zitadel.utils.v1.auth_option) = { + permission: "authenticated" + }; + } } message UserSessionViews { @@ -856,4 +867,52 @@ message ExternalIDPView { string external_user_display_name = 5; google.protobuf.Timestamp creation_date = 6; google.protobuf.Timestamp change_date = 7; -} \ No newline at end of file +} + + +message UserMembershipSearchResponse { + uint64 offset = 1; + uint64 limit = 2; + uint64 total_result = 3; + repeated UserMembershipView result = 4; + uint64 processed_sequence = 5; + google.protobuf.Timestamp view_timestamp = 6; +} + +message UserMembershipSearchRequest { + uint64 offset = 1; + uint64 limit = 2; + repeated UserMembershipSearchQuery queries = 3; +} + +message UserMembershipSearchQuery { + UserMembershipSearchKey key = 1 [(validate.rules).enum = {not_in: [0]}]; + SearchMethod method = 2 [(validate.rules).enum = {in: [0]}]; + string value = 3; +} + +enum UserMembershipSearchKey { + USERMEMBERSHIPSEARCHKEY_UNSPECIFIED = 0; + USERMEMBERSHIPSEARCHKEY_TYPE = 1; + USERMEMBERSHIPSEARCHKEY_OBJECT_ID = 2; +} + +message UserMembershipView { + string user_id = 1; + MemberType member_type = 2; + string aggregate_id = 3; + string object_id = 4; + repeated string roles = 5; + string display_name = 6; + google.protobuf.Timestamp creation_date = 7; + google.protobuf.Timestamp change_date = 8; + uint64 sequence = 9; + string resource_owner = 10; +} + +enum MemberType { + MEMBERTYPE_UNSPECIFIED = 0; + MEMBERTYPE_ORGANISATION = 1; + MEMBERTYPE_PROJECT = 2; + MEMBERTYPE_PROJECT_GRANT = 3; +} diff --git a/pkg/grpc/management/proto/management.proto b/pkg/grpc/management/proto/management.proto index 3f854432b..7cf1e8633 100644 --- a/pkg/grpc/management/proto/management.proto +++ b/pkg/grpc/management/proto/management.proto @@ -778,6 +778,7 @@ service ManagementService { option (caos.zitadel.utils.v1.auth_option) = { permission: "project.read" + check_field_name: "Id" }; } @@ -945,6 +946,18 @@ service ManagementService { }; } + rpc CreateAPIApplication(APIApplicationCreate) returns (Application) { + option (google.api.http) = { + post: "/projects/{project_id}/applications/api" + body: "*" + }; + + option (caos.zitadel.utils.v1.auth_option) = { + permission: "project.app.write" + check_field_name: "ProjectId" + }; + } + rpc UpdateApplication(ApplicationUpdate) returns (Application) { option (google.api.http) = { put: "/projects/{project_id}/applications/{id}" @@ -1016,6 +1029,76 @@ service ManagementService { }; } + rpc UpdateApplicationAPIConfig(APIConfigUpdate) returns (APIConfig) { + option (google.api.http) = { + put: "/projects/{project_id}/applications/{application_id}/apiconfig" + body: "*" + }; + + option (caos.zitadel.utils.v1.auth_option) = { + permission: "project.app.write" + check_field_name: "ProjectId" + }; + } + + rpc RegenerateAPIClientSecret(ApplicationID) returns (ClientSecret) { + option (google.api.http) = { + put: "/projects/{project_id}/applications/{id}/apiconfig/_changeclientsecret" + body: "*" + }; + + option (caos.zitadel.utils.v1.auth_option) = { + permission: "project.app.write" + check_field_name: "ProjectId" + }; + } + + rpc AddClientKey(AddClientKeyRequest) returns (AddClientKeyResponse){ + option (google.api.http) = { + post: "/projects/{project_id}/applications/{application_id}/keys" + body: "*" + }; + + option (caos.zitadel.utils.v1.auth_option) = { + permission: "project.app.write" + check_field_name: "ProjectId" + }; + } + + rpc DeleteClientKey(ClientKeyIDRequest) returns (google.protobuf.Empty) { + option (google.api.http) = { + delete: "/projects/{project_id}/applications/{application_id}/keys/{key_id}" + }; + + option (caos.zitadel.utils.v1.auth_option) = { + permission: "project.app.write" + check_field_name: "ProjectId" + }; + } + + rpc SearchClientKeys(ClientKeySearchRequest) returns (ClientKeySearchResponse) { + option (google.api.http) = { + post: "/projects/{project_id}/applications/{application_id}/keys/_search" + body: "*" + }; + + option (caos.zitadel.utils.v1.auth_option) = { + permission: "project.app.read" + check_field_name: "ProjectId" + }; + } + + rpc GetClientKey(ClientKeyIDRequest) returns (ClientKeyView) { + option (google.api.http) = { + get: "/projects/{project_id}/applications/{application_id}/keys/{key_id}" + }; + + option (caos.zitadel.utils.v1.auth_option) = { + permission: "project.app.read" + check_field_name: "ProjectId" + }; + } + rpc SearchProjectGrants(ProjectGrantSearchRequest) returns (ProjectGrantSearchResponse) { option (google.api.http) = { post: "/projects/{project_id}/grants/_search" @@ -1409,7 +1492,7 @@ service ManagementService { }; option (caos.zitadel.utils.v1.auth_option) = { - permission: "iam.policy.read" + permission: "policy.read" }; } @@ -1420,7 +1503,7 @@ service ManagementService { }; option (caos.zitadel.utils.v1.auth_option) = { - permission: "iam.policy.write" + permission: "policy.write" }; } @@ -1430,7 +1513,7 @@ service ManagementService { }; option (caos.zitadel.utils.v1.auth_option) = { - permission: "iam.policy.write" + permission: "policy.write" }; } @@ -1440,7 +1523,7 @@ service ManagementService { }; option (caos.zitadel.utils.v1.auth_option) = { - permission: "iam.policy.read" + permission: "policy.read" }; } @@ -1451,7 +1534,7 @@ service ManagementService { }; option (caos.zitadel.utils.v1.auth_option) = { - permission: "iam.policy.write" + permission: "policy.write" }; } @@ -1461,7 +1544,7 @@ service ManagementService { }; option (caos.zitadel.utils.v1.auth_option) = { - permission: "iam.policy.write" + permission: "policy.write" }; } @@ -1673,7 +1756,7 @@ service ManagementService { }; } - + rpc GetMailTexts(google.protobuf.Empty) returns (MailTextsView) { option (google.api.http) = { get: "/orgs/me/policies/mailtexts" @@ -1725,7 +1808,7 @@ service ManagementService { permission: "policy.delete" }; } - + } message ZitadelDocs { @@ -2635,6 +2718,7 @@ message Application { string name = 5; oneof app_config { OIDCConfig oidc_config = 8; + APIConfig api_config = 10; } uint64 sequence = 9; } @@ -2683,6 +2767,18 @@ message OIDCApplicationCreate { google.protobuf.Duration clock_skew = 15 [(validate.rules).duration = {gte: {}, lte: {seconds: 5}}]; } +message APIApplicationCreate { + string project_id = 1 [(validate.rules).string = {min_len: 1}]; + string name = 2 [(validate.rules).string = {min_len: 1, max_len: 200}]; + APIAuthMethodType auth_method_type = 3; +} + +message APIConfig { + string client_id = 1; + string client_secret = 2; + APIAuthMethodType auth_method_type = 3; +} + enum OIDCVersion { OIDCV1_0 = 0; } @@ -2709,6 +2805,12 @@ message OIDCConfigUpdate { google.protobuf.Duration clock_skew = 14 [(validate.rules).duration = {gte: {}, lte: {seconds: 5}}]; } +message APIConfigUpdate { + string project_id = 1 [(validate.rules).string = {min_len: 1}]; + string application_id = 2 [(validate.rules).string = {min_len: 1}]; + APIAuthMethodType auth_method_type = 7; +} + enum OIDCResponseType { OIDCRESPONSETYPE_CODE = 0; OIDCRESPONSETYPE_ID_TOKEN = 1; @@ -2731,6 +2833,12 @@ enum OIDCAuthMethodType { OIDCAUTHMETHODTYPE_BASIC = 0; OIDCAUTHMETHODTYPE_POST = 1; OIDCAUTHMETHODTYPE_NONE = 2; + OIDCAUTHMETHODTYPE_PRIVATE_KEY_JWT = 3; +} + +enum APIAuthMethodType { + APIAUTHMETHODTYPE_BASIC = 0; + APIAUTHMETHODTYPE_PRIVATE_KEY_JWT = 1; } message ClientSecret { @@ -2777,6 +2885,60 @@ enum ApplicationSearchKey { APPLICATIONSEARCHKEY_APP_NAME = 1; } +message AddClientKeyRequest { + string project_id = 1 [(validate.rules).string.min_len = 1]; + string application_id = 2 [(validate.rules).string.min_len = 1]; + AuthNKeyType type = 3 [(validate.rules).enum = {not_in: [0]}]; + google.protobuf.Timestamp expiration_date = 4; +} + +message AddClientKeyResponse { + string id = 1; + google.protobuf.Timestamp creation_date = 2; + uint64 sequence = 3; + + AuthNKeyType type = 4; + google.protobuf.Timestamp expiration_date = 5; + bytes key_details = 6; +} + +message ClientKeyIDRequest { + string project_id = 1 [(validate.rules).string.min_len = 1]; + string application_id = 2 [(validate.rules).string.min_len = 1]; + string key_id = 3 [(validate.rules).string.min_len = 1]; +} + +message ClientKeyView { + string id = 1; + AuthNKeyType type = 2; + uint64 sequence = 3; + + google.protobuf.Timestamp creation_date = 4; + google.protobuf.Timestamp expiration_date = 5; +} + +enum AuthNKeyType { + AUTHNKEY_UNSPECIFIED = 0; + AUTHNKEY_JSON = 1; +} + +message ClientKeySearchRequest { + uint64 offset = 1; + uint64 limit = 2; + bool asc = 3; + string project_id = 4 [(validate.rules).string.min_len = 1]; + string application_id = 5 [(validate.rules).string.min_len = 1]; +} + +message ClientKeySearchResponse { + uint64 offset = 1; + uint64 limit = 2; + uint64 total_result = 3; + repeated ClientKeyView result = 4; + uint64 processed_sequence = 5; + google.protobuf.Timestamp view_timestamp = 6; +} + message ProjectGrant { string id = 1; string project_id = 2; @@ -3451,7 +3613,7 @@ message MailText { google.protobuf.Timestamp change_date = 10; } -message MailTextUpdate { +message MailTextUpdate { string mail_text_type = 1; string language = 2; string title = 3; @@ -3462,7 +3624,7 @@ message MailTextUpdate { string button_text = 8; } -message MailTextRemove { +message MailTextRemove { string mail_text_type = 1; string language = 2; } diff --git a/site/config.js b/site/config.js index e2ad88aec..9a3d24fdb 100644 --- a/site/config.js +++ b/site/config.js @@ -1,4 +1,4 @@ export const SLUG_PRESERVE_UNICODE = false; export const SLUG_SEPARATOR = '_'; export const SLUG_LANG = 'en'; -export const LANGUAGES = ['de', 'en']; +export const LANGUAGES = ['en']; diff --git a/site/docs/administrate/00-overview.de.md b/site/docs/administrate/00-overview.de.md deleted file mode 100644 index 43cac2931..000000000 --- a/site/docs/administrate/00-overview.de.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Übersicht ---- - -> This Language is not yet translated. Please consult the English version. diff --git a/site/docs/administrate/00-overview.en.md b/site/docs/administrate/00-overview.md similarity index 88% rename from site/docs/administrate/00-overview.en.md rename to site/docs/administrate/00-overview.md index a7ed64498..d03f204a6 100644 --- a/site/docs/administrate/00-overview.en.md +++ b/site/docs/administrate/00-overview.md @@ -2,6 +2,8 @@ title: Overview --- +This documentation describes the structure of ZITADEL, its role system and in parallel the use of [console](https://console.zitadel.ch), our administration UI for ZITADEL. + > All documentations are under active work and subject to change soon! ### Features diff --git a/site/docs/administrate/01-console.de.md b/site/docs/administrate/01-console.de.md deleted file mode 100644 index 54759f73e..000000000 --- a/site/docs/administrate/01-console.de.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Console ---- - -> This Language is not yet translated. Please consult the English version. diff --git a/site/docs/administrate/01-console.en.md b/site/docs/administrate/01-console.md similarity index 100% rename from site/docs/administrate/01-console.en.md rename to site/docs/administrate/01-console.md diff --git a/site/docs/administrate/02-organisations.de.md b/site/docs/administrate/02-organisations.de.md deleted file mode 100644 index 88fc1ffc1..000000000 --- a/site/docs/administrate/02-organisations.de.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Organisationen ---- - -> This Language is not yet translated. Please consult the English version. diff --git a/site/docs/administrate/02-organisations.en.md b/site/docs/administrate/02-organisations.md similarity index 100% rename from site/docs/administrate/02-organisations.en.md rename to site/docs/administrate/02-organisations.md diff --git a/site/docs/administrate/03-projects.de.md b/site/docs/administrate/03-projects.de.md deleted file mode 100644 index 9421b86c0..000000000 --- a/site/docs/administrate/03-projects.de.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Projekte ---- - -> This Language is not yet translated. Please consult the English version. diff --git a/site/docs/administrate/03-projects.en.md b/site/docs/administrate/03-projects.md similarity index 100% rename from site/docs/administrate/03-projects.en.md rename to site/docs/administrate/03-projects.md diff --git a/site/docs/administrate/04-clients.de.md b/site/docs/administrate/04-clients.de.md deleted file mode 100644 index b7f53dfa1..000000000 --- a/site/docs/administrate/04-clients.de.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Clients ---- - -> This Language is not yet translated. Please consult the English version. diff --git a/site/docs/administrate/04-clients.en.md b/site/docs/administrate/04-clients.md similarity index 98% rename from site/docs/administrate/04-clients.en.md rename to site/docs/administrate/04-clients.md index 4fdc436b2..1de64e4c4 100644 --- a/site/docs/administrate/04-clients.en.md +++ b/site/docs/administrate/04-clients.md @@ -13,7 +13,7 @@ Typical types of applications are: * User Agent (Single-Page-Application) * Native -Check out our [Integration Guide](integrate#Overview) for more information. +Check out our [Integration Guide](quickstarts#Overview) for more information. ### Manage clients diff --git a/site/docs/administrate/05-roles.de.md b/site/docs/administrate/05-roles.de.md deleted file mode 100644 index 26565011a..000000000 --- a/site/docs/administrate/05-roles.de.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Rollen ---- - -> This Language is not yet translated. Please consult the English version. diff --git a/site/docs/administrate/05-roles.en.md b/site/docs/administrate/05-roles.md similarity index 95% rename from site/docs/administrate/05-roles.en.md rename to site/docs/administrate/05-roles.md index 4bd418446..caa4470d3 100644 --- a/site/docs/administrate/05-roles.en.md +++ b/site/docs/administrate/05-roles.md @@ -10,7 +10,7 @@ title: Roles For more information about how **roles** can be consumed, have a look the protocol specific information. -- [OpenID Connect / OAuth](integrate#How_to_consume_authorizations_in_your_application_or_service) +- [OpenID Connect / OAuth](quickstarts#How_to_consume_authorizations_in_your_application_or_service) ### Manage Roles diff --git a/site/docs/administrate/06-users.de.md b/site/docs/administrate/06-users.de.md deleted file mode 100644 index ab58e1c2e..000000000 --- a/site/docs/administrate/06-users.de.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Benutzer ---- - -> This Language is not yet translated. Please consult the English version. diff --git a/site/docs/administrate/06-users.en.md b/site/docs/administrate/06-users.md similarity index 100% rename from site/docs/administrate/06-users.en.md rename to site/docs/administrate/06-users.md diff --git a/site/docs/administrate/07-policies.de.md b/site/docs/administrate/07-policies.de.md deleted file mode 100644 index f78961bec..000000000 --- a/site/docs/administrate/07-policies.de.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Richtlinien ---- - -> This Language is not yet translated. Please consult the English version. diff --git a/site/docs/administrate/07-policies.en.md b/site/docs/administrate/07-policies.md similarity index 100% rename from site/docs/administrate/07-policies.en.md rename to site/docs/administrate/07-policies.md diff --git a/site/docs/administrate/08-providers.de.md b/site/docs/administrate/08-providers.de.md deleted file mode 100644 index 428e170df..000000000 --- a/site/docs/administrate/08-providers.de.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Identitäts Provider ---- - -> This Language is not yet translated. Please consult the English version. diff --git a/site/docs/administrate/08-providers.en.md b/site/docs/administrate/08-providers.md similarity index 100% rename from site/docs/administrate/08-providers.en.md rename to site/docs/administrate/08-providers.md diff --git a/site/docs/administrate/09-authorizations.de.md b/site/docs/administrate/09-authorizations.de.md deleted file mode 100644 index 42e58c92a..000000000 --- a/site/docs/administrate/09-authorizations.de.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Authorizations ---- - -> This Language is not yet translated. Please consult the English version. diff --git a/site/docs/administrate/09-authorizations.en.md b/site/docs/administrate/09-authorizations.md similarity index 100% rename from site/docs/administrate/09-authorizations.en.md rename to site/docs/administrate/09-authorizations.md diff --git a/site/docs/administrate/09-management-roles.de.md b/site/docs/administrate/09-management-roles.de.md deleted file mode 100644 index 95481566c..000000000 --- a/site/docs/administrate/09-management-roles.de.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Management Rollen ---- - -> This Language is not yet translated. Please consult the English version. diff --git a/site/docs/administrate/09-management-roles.en.md b/site/docs/administrate/09-management-roles.md similarity index 100% rename from site/docs/administrate/09-management-roles.en.md rename to site/docs/administrate/09-management-roles.md diff --git a/site/docs/administrate/70-zitadelroles.de.md b/site/docs/administrate/70-zitadelroles.de.md deleted file mode 100644 index d44dec90f..000000000 --- a/site/docs/administrate/70-zitadelroles.de.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: ZITADEL Rollen ---- - -> This Language is not yet translated. Please consult the English version. diff --git a/site/docs/administrate/70-zitadelroles.en.md b/site/docs/administrate/70-zitadelroles.md similarity index 100% rename from site/docs/administrate/70-zitadelroles.en.md rename to site/docs/administrate/70-zitadelroles.md diff --git a/site/docs/administrate/80-audit.de.md b/site/docs/administrate/80-audit.de.md deleted file mode 100644 index abb8125fb..000000000 --- a/site/docs/administrate/80-audit.de.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Audit ---- - -> This Language is not yet translated. Please consult the English version. diff --git a/site/docs/administrate/80-audit.en.md b/site/docs/administrate/80-audit.md similarity index 100% rename from site/docs/administrate/80-audit.en.md rename to site/docs/administrate/80-audit.md diff --git a/site/docs/administrate/90-system.de.md b/site/docs/administrate/90-system.de.md deleted file mode 100644 index 99a0c4ac0..000000000 --- a/site/docs/administrate/90-system.de.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: System Administration ---- - -> This Language is not yet translated. Please consult the English version. diff --git a/site/docs/administrate/90-system.en.md b/site/docs/administrate/90-system.md similarity index 98% rename from site/docs/administrate/90-system.en.md rename to site/docs/administrate/90-system.md index 96b6909ec..4e287ac3e 100644 --- a/site/docs/administrate/90-system.en.md +++ b/site/docs/administrate/90-system.md @@ -38,7 +38,7 @@ There is even a possibility to regenerate a read model. -> Additional infos to the architecture of ZITADEL is located in [Architecture Docs](documentation#Architecture) +> Additional infos to the architecture of ZITADEL is located in [Architecture Docs](architecture#Architecture) ### Secret Handling diff --git a/site/docs/administrate/seo_de.html b/site/docs/administrate/seo_de.html deleted file mode 100644 index 19e0f914f..000000000 --- a/site/docs/administrate/seo_de.html +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/site/docs/administrate/seo_en.html b/site/docs/administrate/seo_en.html deleted file mode 100644 index ec0b59a18..000000000 --- a/site/docs/administrate/seo_en.html +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/site/docs/angular/00-overview.md b/site/docs/angular/00-overview.md new file mode 100644 index 000000000..19a97dd7c --- /dev/null +++ b/site/docs/angular/00-overview.md @@ -0,0 +1,16 @@ +--- +title: Angular +--- + +
+ zitadel + + angular +
+ +This Integration guide shows you the recommended way to integrate **ZITADEL** into your Angular Application. +It demonstrates how to add a user login to your application and fetch some data from the user info endpoint. + +At the end of the guide you should have an application able to login a user and read the user profile. + +> Note that our **ZITADEL Console** is also written in Angular and can therefore be used as a reference. \ No newline at end of file diff --git a/site/docs/angular/01-configure.md b/site/docs/angular/01-configure.md new file mode 100644 index 000000000..690bafa6b --- /dev/null +++ b/site/docs/angular/01-configure.md @@ -0,0 +1,29 @@ +--- +title: Configure Zitadel +--- + +### Setup Application and get Keys + +Before we can start building our application we have do do a few configuration steps in ZITADEL Console. +You will need to provide some information about your app. We recommend creating a new app to start from scratch. Navigate to your [Project](https://console.zitadel.ch/projects) and add a new application at the top of the page. +Select Web Application and continue. +We recommend that you use [Authorization Code](architecture#Authorization_Code) in combination with [Proof Key for Code Exchange](architecture#Proof_Key_for_Code_Exchange) for all web applications. + +> Make sure Authentication Method is set to `NONE` and the Application Type is set to `SPA` or `NATIVE`. + +#### Redirect URLs + +A redirect URL is a URL in your application where ZITADEL redirects the user after they have authenticated. Set your url to the domain the web app will be deployed to or use `localhost:4200` for development as Angular will be running on port 4200. + +> If you are following along with the sample project you downloaded from our templates, you should set the Allowed Callback URL to http://localhost:4200/auth/callback. You will also have to set dev mode to `true` as this will enable unsecure http for the moment. + +If you want to redirect the users back to a route on your application after they have logged out, add an optional redirect in the post redirectURI field. + +Continue and Create the application. + +#### Client ID and Secret + +After successful app creation a popup will appear showing you your clientID as well as a secret. +Copy your client ID as it will be needed in the next step. + +> Note: You will be able to regenerate the secret at a later time, though it is not needed for SPAs with Authorization Code Flow. diff --git a/site/docs/angular/02-code.md b/site/docs/angular/02-code.md new file mode 100644 index 000000000..b2596a67d --- /dev/null +++ b/site/docs/angular/02-code.md @@ -0,0 +1,198 @@ +--- +title: Angular Setup +--- + +### Install Angular dependencies + +You need to install an oauth / oidc client to connect with ZITADEL. Run the following command: + +```bash +npm install angular-oauth2-oidc +``` + +This library helps integrating ZITADEL Authentication in your Angular Application. + +### Create and configure Auth Module + +Add the Auth module to your Angular imports in AppModule and setup the AuthConfig in a constant above. + +```ts +... +import { AuthConfig, OAuthModule } from 'angular-oauth2-oidc'; + +const authConfig: AuthConfig = { + clientId: 'YOUR CLIENT ID', + redirectUri: 'http://localhost:4200/auth/callback', // change this to your domain later or use window.location.origin. + scope: 'openid profile email', + responseType: 'code', + oidc: true, +}; + +@NgModule({ + declarations: [ + AppComponent, + SignedoutComponent, + ], + imports: [ + OAuthModule..forRoot(), +... +``` + +Set **openid**, **profile** and **email** as scope, **code** as responseType, and oidc to **true**. +Then create a Authentication Service to provide the functions to authenticate your user. + +You can use Angulars schematics to do so: + +``` bash +ng g component services/auth +``` +This will create an AuthService automatically for you. + +Copy the following code to your service. This code provides a function `authenticate()` which redirects the user to ZITADEL. After the user has logged in it will be redirected back to your redirectURI set in Auth Module and Console. Make sure both correspond, otherwise ZITADEL will throw an error. + +```ts +import { AuthConfig, OAuthService } from 'angular-oauth2-oidc'; + +export default class AuthService { + private authConfig!: AuthConfig; + private _authenticated: boolean = false; + private readonly _authenticationChanged: BehaviorSubject< + boolean + > = new BehaviorSubject(this.authenticated); + + constructor( + private oauthService: OAuthService, + private statehandler: StatehandlerService, + ) { } + + public get authenticated(): boolean { + return this._authenticated; + } + + public get authenticationChanged(): Observable { + return this._authenticationChanged; + } + + public getOIDCUser(): Observable { + return from(this.oauthService.loadUserProfile()); + } + + public async authenticate(): Promise { + this.oauthService.configure(this.authConfig); + + this.oauthService.strictDiscoveryDocumentValidation = false; + await this.oauthService.loadDiscoveryDocumentAndTryLogin(); + + this._authenticated = this.oauthService.hasValidAccessToken(); + + if (!this.oauthService.hasValidIdToken() || !this.authenticated || partialConfig || force) { + const newState = setState ? await this.statehandler.createState().toPromise() : undefined; + this.oauthService.initCodeFlow(newState); + } + this._authenticationChanged.next(this.authenticated); + + return this.authenticated; + } + + public signout(): void { + this.oauthService.logOut(); + this._authenticated = false; + this._authenticationChanged.next(false); + } +} +``` + +### Add Login in your application + +To login a user, a component or a guard is needed. + +- A component provides a button prompting the user to start the login flow. +`authenticate()` redirects your user to ZITADEL.ch for authentication. Upon successfull Authentication, ZITADEL will redirect the user back to your previously defined Redirect URL. + +- A guard can be setup to check if the user has a valid **Access Token** to proceed. This will check if the user has a stored **accesstoken** in storage or otherwise prompt the user to login. + +The use of this components totally depends on your application. In most cases you need both. + +To create a component use +``` bash +ng g component components/login +``` +and then inject the authService to call `authenticate()`. + +Same for the guard: +``` bash +ng g guard guards/auth +``` + +This code shows the AuthGuard used in our Console. + +```ts +import { AuthService } from 'src/app/services/auth.service'; + +@Injectable({ + providedIn: 'root', +}) +export class AuthGuard implements CanActivate { + constructor(private auth: AuthService) { } + + public canActivate( + _: ActivatedRouteSnapshot, + state: RouterStateSnapshot, + ): Observable | Promise | boolean { + if (!this.auth.authenticated) { + return this.auth.authenticate(); + } + return this.auth.authenticated; + } +} +``` + +it can easily be added to your RouterModule. + +```ts +... +const routes: Routes = [ + { + path: '', + loadChildren: () => import('./pages/home/home.module').then(m => m.HomeModule), + canActivate: [AuthGuard], + }, +... +``` + +### Add Logout in your application + +The authService and Library also provides a useful function for logging out your users. Just call `auth.signout()` to log out your user. Note that you can also configure your Logout Redirect URL if you want your Users to be redirected after logout. + +```ts +import { AuthService } from 'src/app/services/auth.service.ts'; + +export class SomeComponentWithLogout { + constructor(private authService: AuthService){} + + public signout(): Promise { + return this.authService.signout(); + } +} +``` + +### Show User Information + +To fetch user data, ZITADELS user info endpoint has to be called. This data contains sensitive information and artifacts related to your users identity and the scopes you defined in your Auth Config. +Our AuthService already includes a function called getOIDCUser(). You can call it whereever you need this information. + +```ts +import { AuthService } from 'src/app/services/auth.service.ts'; + +export class SomeComponentWithUserInfo { + constructor(public authService: AuthService){} +} +``` + +and in your html + +```html +
+

{{oidcInfo | json}}

+
+``` \ No newline at end of file diff --git a/site/docs/angular/03-end.md b/site/docs/angular/03-end.md new file mode 100644 index 000000000..813951aff --- /dev/null +++ b/site/docs/angular/03-end.md @@ -0,0 +1,9 @@ +--- +title: Completion +--- + +### What next? + +You have successfully integrated ZITADEL in your Angular Application! Now you can proceed implementing our APIs to include Authorization. Refer to our [Docs](apis#Authentication_API) or checkout our Console Code on [Github](https://github.com/caos/zitadel) which is using GRPC to access data. + +For more information about creating an angular application we refer to [Angular](https://angular.io/start) and for more information about the used oauth/oidc library consider reading their docs at [angular-oauth2-oidc](https://github.com/manfredsteyer/angular-oauth2-oidc). \ No newline at end of file diff --git a/site/docs/develop/00-overview.en.md b/site/docs/apis/00-overview.md similarity index 95% rename from site/docs/develop/00-overview.en.md rename to site/docs/apis/00-overview.md index ec508cc0a..8af2ffed1 100644 --- a/site/docs/develop/00-overview.en.md +++ b/site/docs/apis/00-overview.md @@ -3,6 +3,8 @@ title: Overview description: … --- + + > All documentations are under active work and subject to change soon! ### APIs diff --git a/site/docs/develop/01-authentication.en.md b/site/docs/apis/01-authentication.md similarity index 100% rename from site/docs/develop/01-authentication.en.md rename to site/docs/apis/01-authentication.md diff --git a/site/docs/develop/02-management.en.md b/site/docs/apis/02-management.md similarity index 100% rename from site/docs/develop/02-management.en.md rename to site/docs/apis/02-management.md diff --git a/site/docs/develop/03-administration.en.md b/site/docs/apis/03-administration.md similarity index 100% rename from site/docs/develop/03-administration.en.md rename to site/docs/apis/03-administration.md diff --git a/site/docs/documentation/00-overview.en.md b/site/docs/architecture/00-overview.md similarity index 83% rename from site/docs/documentation/00-overview.en.md rename to site/docs/architecture/00-overview.md index aab91c5df..577cde721 100644 --- a/site/docs/documentation/00-overview.en.md +++ b/site/docs/architecture/00-overview.md @@ -2,6 +2,8 @@ title: Overview --- + + > All documentations are under active work and subject to change soon! This part of the **ZITADEL** documentation comprises three major subject areas: diff --git a/site/docs/documentation/01-priciples.en.md b/site/docs/architecture/01-priciples.md similarity index 100% rename from site/docs/documentation/01-priciples.en.md rename to site/docs/architecture/01-priciples.md diff --git a/site/docs/documentation/02-architecture.en.md b/site/docs/architecture/02-architecture.md similarity index 99% rename from site/docs/documentation/02-architecture.en.md rename to site/docs/architecture/02-architecture.md index 9d7b98667..6921af9e9 100644 --- a/site/docs/documentation/02-architecture.en.md +++ b/site/docs/architecture/02-architecture.md @@ -97,3 +97,4 @@ With this design even the outage of a whole data-center would have a minimal imp
Multi-Cluster Architecture
+ diff --git a/site/docs/documentation/03-openidoauth.en.md b/site/docs/architecture/03-openidoauth.md similarity index 97% rename from site/docs/documentation/03-openidoauth.en.md rename to site/docs/architecture/03-openidoauth.md index 6f961bd1b..3e22faaec 100644 --- a/site/docs/documentation/03-openidoauth.en.md +++ b/site/docs/architecture/03-openidoauth.md @@ -3,22 +3,21 @@ title: OpenID Connect 1.0 & OAuth 2.0 --- ### Endpoints and Domains - This chapter documents the [OpenID Connect 1.0](https://openid.net/connect/) and [OAuth 2.0](https://oauth.net/2/) features provided by **ZITADEL**. Under normal circumstances **ZITADEL** need four domain names to operate properly. | Domain Name | Example | Description | |:------------|:----------------------|--------------------------------------------------------------------------------------------------------------------------------------| -| issuer | `issuer.zitadel.ch` | Provides the [OpenID Connect 1.0 Discovery Endpoint](#openid-connect-10-discovery) | -| api | `api.zitadel.ch` | All ZITADEL API's are located under this domain see [API explanation](develop#APIs) for details | +| issuer | `issuer.zitadel.ch` | Provides the [OpenID Connect 1.0 Discovery Endpoint](#OpenID_Connect_1_0_Discovery) | +| api | `api.zitadel.ch` | All ZITADEL API's are located under this domain see [API explanation](apis#APIs) for details | | login | `accounts.zitadel.ch` | The accounts.* page provides server renderer pages like login and register and as well the authorization_endpoint for OpenID Connect | | console | `console.zitadel.ch` | With the console.* domain we serve the assets for the management gui | #### OpenID Connect 1.0 Discovery The OpenID Connect Discovery Endpoint is located within the issuer domain. -For example with [zitadel.ch](zitadel.ch) this would be the domain [issuer.zitadel.ch](issuer.zitadel.ch). This would give us [https://issuer.zitadel.ch/.well-known/openid-configuration](https://issuer.zitadel.ch/.well-known/openid-configuration). +For example with [zitadel.ch](https://zitadel.ch), issuer.zitadel.ch would be the domain. This would give us [https://issuer.zitadel.ch/.well-known/openid-configuration](https://issuer.zitadel.ch/.well-known/openid-configuration). **Link to spec.** [OpenID Connect Discovery 1.0 incorporating errata set 1](https://openid.net/specs/openid-connect-discovery-1_0.html) @@ -50,7 +49,7 @@ For example with [zitadel.ch](zitadel.ch) this would be the domain [issuer.zitad #### OAuth 2.0 Metadata -**ZITADEL** does not yet provide a OAuth 2.0 Metadata endpoint but instead provides a [OpenID Connect Discovery Endpoint](#openid-connect-10-discovery). +**ZITADEL** does not yet provide a OAuth 2.0 Metadata endpoint but instead provides a [OpenID Connect Discovery Endpoint](#OpenID_Connect_1_0_Discovery). ### Scopes @@ -287,3 +286,4 @@ curl --request POST \ #### Security Assertion Markup Language (SAML) 2.0 Profile **Link to spec.** [Security Assertion Markup Language (SAML) 2.0 Profile for OAuth 2.0 Client Authentication and Authorization Grants](https://tools.ietf.org/html/rfc7522) + diff --git a/site/docs/aspnet/00-overview.md b/site/docs/aspnet/00-overview.md new file mode 100644 index 000000000..1f8f346f8 --- /dev/null +++ b/site/docs/aspnet/00-overview.md @@ -0,0 +1,15 @@ +--- +title: ASP.NET Auth and Authz +description: ... +--- + +
+ zitadel + + aspnet +
+ + +> This quickstart is not yet released. Come back later! + +This Integration guide shows you the recommended way on how to integrate **ZITADEL** into your ASP NET Backend. diff --git a/site/docs/develop/00-overview.de.md b/site/docs/develop/00-overview.de.md deleted file mode 100644 index ee626691f..000000000 --- a/site/docs/develop/00-overview.de.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Übersicht -description: … ---- - -> This Language is not yet translated. Please consult the English version. diff --git a/site/docs/develop/01-authentication.de.md b/site/docs/develop/01-authentication.de.md deleted file mode 100644 index ee94e19c7..000000000 --- a/site/docs/develop/01-authentication.de.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Authentication API -description: … ---- - -> This Language is not yet translated. Please consult the English version. diff --git a/site/docs/develop/02-management.de.md b/site/docs/develop/02-management.de.md deleted file mode 100644 index 18adf5bf6..000000000 --- a/site/docs/develop/02-management.de.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Management API -description: … ---- - -> This Language is not yet translated. Please consult the English version. diff --git a/site/docs/develop/03-administration.de.md b/site/docs/develop/03-administration.de.md deleted file mode 100644 index b6b59725b..000000000 --- a/site/docs/develop/03-administration.de.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Admin API -description: … ---- - -> This Language is not yet translated. Please consult the English version. diff --git a/site/docs/documentation/00-overview.de.md b/site/docs/documentation/00-overview.de.md deleted file mode 100644 index 6d9be1de6..000000000 --- a/site/docs/documentation/00-overview.de.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Übersicht ---- - -> This Language is not yet translated. Please consult the English version. \ No newline at end of file diff --git a/site/docs/documentation/01-priciples.de.md b/site/docs/documentation/01-priciples.de.md deleted file mode 100644 index 51456b6b6..000000000 --- a/site/docs/documentation/01-priciples.de.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: Prinzipien ---- - -- Seien Sie bei Ihren Entscheidungen transparent -- Zustandsloses Anwendungsdesign -- Das System der Aufzeichnungen ist der Ereignisspeicher -- Alles andere muss regeneriert werden können -- Versuchen Sie nicht, komplexe Probleme außerhalb des IAM-Bereichs zu lösen -- Verwenden Sie skalierbaren Speicher für den Ereignisspeicher und die Abfragemodelle -- Versuchen Sie, wenn immer möglich idempotent zu sein -- Reduzieren Sie die Notwendigkeit von System- oder externen Abhängigkeiten so weit wie möglich -- Automatisierung einbeziehen -- Zuerst die Design-API -- Optimieren Sie alle Komponenten für den Betrieb am zweiten Tag -- Verwenden Sie nur Open-Source-Projekte mit permissiven Lizenzen -- Rollen Sie nicht Ihre eigene Krypto -- Standard so weit wie möglich einbeziehen -- Nutzen Sie die Funktionen der Plattform -- Mit einem CDN und einer WAF laufen können diff --git a/site/docs/documentation/02-architecture.de.md b/site/docs/documentation/02-architecture.de.md deleted file mode 100644 index 3f807cab7..000000000 --- a/site/docs/documentation/02-architecture.de.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Architektur ---- - -> TBD diff --git a/site/docs/documentation/03-openidoauth.de.md b/site/docs/documentation/03-openidoauth.de.md deleted file mode 100644 index 98d47d61d..000000000 --- a/site/docs/documentation/03-openidoauth.de.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: OpenID Connect 1.0 & OAuth 2.0 ---- - -> TBD diff --git a/site/docs/export-log b/site/docs/export-log new file mode 100644 index 000000000..8680b49e1 --- /dev/null +++ b/site/docs/export-log @@ -0,0 +1,78 @@ + 4.66 kB service-worker-index.html + 10.5 kB index.html + 1.15 kB icons/favicon.ico + 481 B manifest.json + 3.17 kB prism.css + 11.6 kB default-skin/default-skin.css + 14.8 kB client/client-48a0d285.css + 3.88 kB client/index-5d76bab7.css + 4.14 kB photoswipe.css + 33.9 kB client/client.ea30bda8.js + 559 B client/inject_styles.5607aec6.js + 18.1 kB client/index.6f1d050b.js + 5.54 kB start.json + 967 B quickstarts.json + 6.45 kB logos/zitadel-logo-light.svg + 8.3 kB logos/zitadel-logo-solo-darkdesign.svg + 18 kB start/index.html + 14.9 kB img/develop2.png + 10.1 kB img/projects2.png + 11.1 kB img/personal2.png + 7.96 kB quickstarts/index.html + 15.2 kB use/index.html + 22.8 kB apis/index.html + 73.1 kB img/accounts_org_register.png + 10.3 kB client/[slug]-3cb415b8.css + 1.52 kB client/index-4d174bf5.css + 20.7 kB client/[slug].aebb20dc.js + 4.16 kB client/index.c2043c63.js + 114 kB architecture/index.html + 207 kB img/accounts_password.png + 199 kB img/accounts_page.png + 899 B tech/angular.svg + 1.79 kB tech/dart.svg + 2.29 kB tech/golang.svg + 200 kB img/accounts_otp_verify.png + 21.3 kB img/zitadel_software_architecture.png + 10.4 kB img/zitadel_cluster_architecture.png + 184 kB administrate/index.html + 39 kB angular/index.html + 38.9 kB dart/index.html + 38.8 kB go/index.html + 7.37 kB img/zitadel_multicluster_architecture.png + 31 kB img/console_user_entry.png + 83.5 kB img/console_admin_entry.png + 167 kB img/console_admin_system.png + 129 kB img/console_org_domain_default.png + 126 kB img/console_org_domain_add.png + 142 kB img/console_org_domain_added.png + 126 kB img/console_user_personal_information.png + 135 kB img/console_org_domain_verify.png + 52.8 kB img/console_user_personal_info.png + 15 kB img/console_projects_empty.png + 40.2 kB img/console_projects_my_first_project.png + 40.7 kB img/console_org_domain_verified.png + 178 kB img/console_org_manage_roles_2.png + 129 kB img/console_org_manage_roles_1.png + 38.1 kB img/console_org_domain_verify_dns.png + 112 kB img/console_project_manage_roles_1.png + 19.5 kB img/console_clients_my_first_spa_wizard_1.png + 21.6 kB img/console_clients_my_first_spa_wizard_4.png + 22.3 kB img/console_clients_my_first_spa_wizard_3.png + 28.3 kB img/console_clients_my_first_spa_config.png + 27.1 kB img/console_user_list_search.png + 159 kB img/console_project_manage_roles_2.png + 25.2 kB img/console_user_list.png + 16.3 kB img/console_clients_my_first_spa_wizard_2.png + 38.8 kB img/console_authz_add_1.png + 77.2 kB administrate.json + 26.6 kB img/console_authz_overview.png + 186 kB img/console_user_manage_roles_1.png + 47.9 kB img/console_user_manage_roles_2.png + 110 kB img/console_user_create_done.png + 36.1 kB img/console_authz_add_2.png + 34.1 kB img/console_authz_add_3.png + 29.6 kB img/console_user_create_form.png + 6.53 kB apis.json + 142 kB img/console_iam_admin_failed.png + 167 kB img/console_iam_admin_views.png \ No newline at end of file diff --git a/site/docs/flutter/00-overview.md b/site/docs/flutter/00-overview.md new file mode 100644 index 000000000..d4e370f3b --- /dev/null +++ b/site/docs/flutter/00-overview.md @@ -0,0 +1,14 @@ +--- +title: Flutter Login +description: ... +--- + +
+ zitadel + + flutter +
+ +> This quickstart is not yet released. Come back later! + +This Integration guide shows you the recommended way on how to integrate **ZITADEL** into your Dart Application. diff --git a/site/docs/go/00-overview.md b/site/docs/go/00-overview.md new file mode 100644 index 000000000..af5fafb42 --- /dev/null +++ b/site/docs/go/00-overview.md @@ -0,0 +1,15 @@ +--- +title: Dart Login +description: ... +--- + +
+ zitadel + + golang +
+ + +> This quickstart is not yet released. Come back later! + +This Integration guide shows you the recommended way on how to integrate **ZITADEL** into your Go Lang Backend. diff --git a/site/docs/integrate/00-overview.de.md b/site/docs/integrate/00-overview.de.md deleted file mode 100644 index 5057e686a..000000000 --- a/site/docs/integrate/00-overview.de.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Übersicht -description: ... ---- - -> This Language is not yet translated. Please consult the English version. diff --git a/site/docs/integrate/01-singlepageapp.de.md b/site/docs/integrate/01-singlepageapp.de.md deleted file mode 100644 index 5766daed2..000000000 --- a/site/docs/integrate/01-singlepageapp.de.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Single Page Application -description: ... ---- - -> This Language is not yet translated. Please consult the English version. diff --git a/site/docs/integrate/02-serverapp.de.md b/site/docs/integrate/02-serverapp.de.md deleted file mode 100644 index 7fa851534..000000000 --- a/site/docs/integrate/02-serverapp.de.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Server Side Application -description: ... ---- - -> This Language is not yet translated. Please consult the English version. diff --git a/site/docs/integrate/03-mobileapp.de.md b/site/docs/integrate/03-mobileapp.de.md deleted file mode 100644 index 085e060c0..000000000 --- a/site/docs/integrate/03-mobileapp.de.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Mobile Application -description: ... ---- - -> This Language is not yet translated. Please consult the English version. diff --git a/site/docs/integrate/04-nativeapp.de.md b/site/docs/integrate/04-nativeapp.de.md deleted file mode 100644 index a96998467..000000000 --- a/site/docs/integrate/04-nativeapp.de.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Native Application -description: ... ---- - -> This Language is not yet translated. Please consult the English version. diff --git a/site/docs/integrate/05-proxy.de.md b/site/docs/integrate/05-proxy.de.md deleted file mode 100644 index 5a605d796..000000000 --- a/site/docs/integrate/05-proxy.de.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Proxy / WAF -description: ... ---- - -> This Language is not yet translated. Please consult the English version. diff --git a/site/docs/integrate/06-api.de.md b/site/docs/integrate/06-api.de.md deleted file mode 100644 index a4961d6a2..000000000 --- a/site/docs/integrate/06-api.de.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: API -description: ... ---- - -> This Language is not yet translated. Please consult the English version. diff --git a/site/docs/integrate/07-products.de.md b/site/docs/integrate/07-products.de.md deleted file mode 100644 index 9eaf2a981..000000000 --- a/site/docs/integrate/07-products.de.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Products -description: ... ---- - -> This Language is not yet translated. Please consult the English version. diff --git a/site/docs/oauth2-proxy/00-overview.md b/site/docs/oauth2-proxy/00-overview.md new file mode 100644 index 000000000..165e1bbe8 --- /dev/null +++ b/site/docs/oauth2-proxy/00-overview.md @@ -0,0 +1,13 @@ +--- +title: OAuth 2.0 Proxy +--- + +
+ zitadel + + oauth2-proxy +
+ +### OAuth2 Proxy Project + +[OAuth2-proxy](https://github.com/oauth2-proxy/oauth2-proxy) is a project which allows services to delegate the authentication flow to a IDP, for example **ZITADEL** \ No newline at end of file diff --git a/site/docs/oauth2-proxy/01-configure-zitadel.md b/site/docs/oauth2-proxy/01-configure-zitadel.md new file mode 100644 index 000000000..5a763fdb7 --- /dev/null +++ b/site/docs/oauth2-proxy/01-configure-zitadel.md @@ -0,0 +1,29 @@ +--- +title: Configure Zitadel +--- + +### Setup Application and get Keys + +Before we can start building our application we have do do a few configuration steps in ZITADEL Console. +You will need to provide some information about your app. We recommend creating a new app to start from scratch. Navigate to your [Project](https://console.zitadel.ch/projects) and add a new application at the top of the page. +Select Web Application and continue. +We recommend that you use [Authorization Code](architecture#Authorization_Code) for the OAuth 2.0 Proxy. + +> Make sure Authentication Method is set to `BASIC` and the Application Type is set to `Web`. + +#### Redirect URLs + +A redirect URL is a URL in your application where ZITADEL redirects the user after they have authenticated. Set your url to the domain the proxy will be deployed to or use the default one `http://127.0.0.1:4180/oauth2/callback`. + +> If you are following along with the sample project you downloaded from our templates, you should set the Allowed Callback URL to http://localhost:4200/auth/callback. You will also have to set dev mode to `true` as this will enable unsecure http for the moment. + +If you want to redirect the users back to a route on your application after they have logged out, add an optional redirect in the post redirectURI field. + +Continue and Create the application. + +#### Client ID and Secret + +After successful app creation a popup will appear showing you your clientID as well as a secret. +Copy your client ID and Secrets as it will be needed in the next step. + +> Note: You will be able to regenerate the secret at a later time if you loose it. diff --git a/site/docs/oauth2-proxy/02-configure-proxy.md b/site/docs/oauth2-proxy/02-configure-proxy.md new file mode 100644 index 000000000..7d515b76a --- /dev/null +++ b/site/docs/oauth2-proxy/02-configure-proxy.md @@ -0,0 +1,28 @@ +--- +title: OAuth 2.0 Proxy Setup +--- + +### Authentication Example + +```toml +provider = "oidc" +user_id_claim = "sub" #uses the subject as ID instead of the email +provider_display_name = "ZITADEL" +redirect_url = "http://127.0.0.1:4180/oauth2/callback" +oidc_issuer_url = "https://issuer.zitadel.ch" +upstreams = [ + "https://example.corp.com" +] +email_domains = [ + "*" +] +client_id = "{ZITADEL_GENERATED_CLIENT_ID}" +client_secret = "{ZITADEL_GENERATED_CLIENT_SECRET}" +pass_access_token = true +cookie_secret = "{SUPPLY_SOME_SECRET_HERE}" +skip_provider_button = true +cookie_secure = false #localdev only false +http_address = "127.0.0.1:4180" #localdev only +``` + +> This was tested with version `oauth2-proxy v6.1.1 (built with go1.14.2)` \ No newline at end of file diff --git a/site/docs/oauth2-proxy/03-end.md b/site/docs/oauth2-proxy/03-end.md new file mode 100644 index 000000000..ede964b4d --- /dev/null +++ b/site/docs/oauth2-proxy/03-end.md @@ -0,0 +1,7 @@ +--- +title: Completion +--- + +### What next? + +You have successfully integrated ZITADEL in your proxy! \ No newline at end of file diff --git a/site/docs/integrate/00-overview.en.md b/site/docs/quickstarts/00-overview.md similarity index 67% rename from site/docs/integrate/00-overview.en.md rename to site/docs/quickstarts/00-overview.md index 6dcc0a212..b549f3d61 100644 --- a/site/docs/integrate/00-overview.en.md +++ b/site/docs/quickstarts/00-overview.md @@ -13,4 +13,4 @@ This Integration guide gives you recommendations on how to integrate different C - Native App - Reverse Proxy -For more details about how **ZITADEL** treats [scopes](documentation#Scopes) and [claims](documentation#Claims) see the [documentations](documentation). +For more details about how **ZITADEL** treats [scopes](architecture#Scopes) and [claims](architecture#Claims) see the [documentations](architecture). diff --git a/site/docs/integrate/01-singlepageapp.en.md b/site/docs/quickstarts/01-singlepageapp.md similarity index 91% rename from site/docs/integrate/01-singlepageapp.en.md rename to site/docs/quickstarts/01-singlepageapp.md index 4617f720a..063f8a8d6 100644 --- a/site/docs/integrate/01-singlepageapp.en.md +++ b/site/docs/quickstarts/01-singlepageapp.md @@ -5,7 +5,7 @@ description: ... ### SPA Protocol and Flow recommendation -If your [client](administrate#Clients) is a single page application (SPA) we recommend that you use [Authorization Code](documentation#Authorization_Code) in combination with [Proof Key for Code Exchange](documentation#Proof_Key_for_Code_Exchange). +If your [client](administrate#Clients) is a single page application (SPA) we recommend that you use [Authorization Code](architecture#Authorization_Code) in combination with [Proof Key for Code Exchange](architecture#Proof_Key_for_Code_Exchange). This flow has great support with most modern languages and frameworks and is the recommended default. diff --git a/site/docs/integrate/02-serverapp.en.md b/site/docs/quickstarts/02-serverapp.md similarity index 100% rename from site/docs/integrate/02-serverapp.en.md rename to site/docs/quickstarts/02-serverapp.md diff --git a/site/docs/integrate/03-mobileapp.en.md b/site/docs/quickstarts/03-mobileapp.md similarity index 100% rename from site/docs/integrate/03-mobileapp.en.md rename to site/docs/quickstarts/03-mobileapp.md diff --git a/site/docs/integrate/04-nativeapp.en.md b/site/docs/quickstarts/04-nativeapp.md similarity index 100% rename from site/docs/integrate/04-nativeapp.en.md rename to site/docs/quickstarts/04-nativeapp.md diff --git a/site/docs/integrate/05-proxy.en.md b/site/docs/quickstarts/05-proxy.md similarity index 100% rename from site/docs/integrate/05-proxy.en.md rename to site/docs/quickstarts/05-proxy.md diff --git a/site/docs/integrate/06-api.en.md b/site/docs/quickstarts/06-api.md similarity index 100% rename from site/docs/integrate/06-api.en.md rename to site/docs/quickstarts/06-api.md diff --git a/site/docs/integrate/07-products.en.md b/site/docs/quickstarts/07-products.md similarity index 100% rename from site/docs/integrate/07-products.en.md rename to site/docs/quickstarts/07-products.md diff --git a/site/docs/start/00-quick-start.de.md b/site/docs/start/00-quick-start.de.md deleted file mode 100644 index 8f73dcc2f..000000000 --- a/site/docs/start/00-quick-start.de.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Schnellstart -description: ... ---- - -> This Language is not yet translated. Please consult the English version. diff --git a/site/docs/start/00-quick-start.en.md b/site/docs/start/00-quick-start.en.md deleted file mode 100644 index 0dc659a15..000000000 --- a/site/docs/start/00-quick-start.en.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -title: Quick-Start -description: A quick-start reference for the impatient reader. ---- - -> All documentations are under active work and subject to change soon! - -### Trying out ZITADEL - -You can either use our cloud-instance [ZITADEL.ch](https://zitadel.ch) or deploy a dedicated **ZITADEL** instance. To get started, we recommend you try out our free tier on [ZITADEL.ch](https://zitadel.ch). - -### Use ZITADEL.ch - -To use ZITADEL in your project you need to: -1. Set up a new [client](administrate#What_are_clients) and [users](administrate#What_are_users) in our [Console](administrate#What_is_Console); -2. Configure your project to use ZITADEL. - -To register your free [organisation](administrate#Organisations), visit this link [register organisation](https://accounts.zitadel.ch/register/org). -After accepting the TOS and filling out all the required fields you will receive an email with further instructions. - - - -#### Verify your domain name (optional) - -When you verify your domain you get the benefit that your [organisations](administrate#Organisations) [users](administrate#Users) can use this domain as **preferred logonname**. You find a more detailed explanation [How ZITADEL handles usernames](administrate#How_ZITADEL_handles_usernames). - -The verification process is documented [here](administrate#Verify_a_domain_name) - -#### Add Users to your organisation - -To add new user just follow [this guide](administrate#Create_Users) - -#### Setup an application - -First [create a project](administrate#Create_a_project) - -Then create within this [project](administrate#Projects) a [new client](administrate#Create_a_client) - -The wizard should provide some guidance what client is the proper for you. If you are still unsure consult our [Integration Guide](integrate#Overview) - -### Use ORBOS to install ZITADEL - -> This will be added later on - -### Install ZITADEL with static manifest - -> This will be added later on diff --git a/site/docs/start/00-quick-start.md b/site/docs/start/00-quick-start.md new file mode 100644 index 000000000..9c746c50b --- /dev/null +++ b/site/docs/start/00-quick-start.md @@ -0,0 +1,19 @@ +--- +title: Welcome to ZITADEL +description: A quick-start reference for the impatient reader. +--- + +Most applications need to know the identity of a user allowing to securely store user data in the cloud and provide the same personalised experience across all of the user's devices. + +ZITADEL's authentication provides backend services, easy-to-use SDKs, and ready-made UI libraries to authenticate users in your application. It supports authentication using passwords and applies additional security with the help of a second factor, for example OTP, to ensure a safe and secure access. +It additionally leverages industry standards like OAuth 2.0 and OpenID Connect such that it can be easily integrated in your custom backend. + +This documentation demonstrates the different installation methods of ZITADEL and provides a quick start guide on how to register your organization as well as creating your first project. + +> All documentations are under active work and subject to change soon! + +## Trying out ZITADEL + +### Installation Types + +You can either use our cloud-instance [zitadel.ch](https://zitadel.ch) or deploy a dedicated **ZITADEL** instance. To get started, we recommend you to try out our free tier first. diff --git a/site/docs/start/01-zitadel-ch.md b/site/docs/start/01-zitadel-ch.md new file mode 100644 index 000000000..77e310a69 --- /dev/null +++ b/site/docs/start/01-zitadel-ch.md @@ -0,0 +1,39 @@ +--- +title: ZITADEL.ch +description: A quick-start reference to use our cloud instance zitadel.ch +--- + +### Use cloud instance zitadel.ch + +To create a ZITADEL project, you have to register as an organization first. Click [here](https://accounts.zitadel.ch/register/org) to register. +You will receive an email prompting you to verify your mail. +Then go to your [Console Projects](https://console.zitadel.ch/projects) view and create a new project. + + + +Now you can proceed adding [users](administrate#What_are_users) to your organization as well as integrating your applications. We refer to our administration [documentation](administrate#What_are_clients) as well as our [quickstarts](quickstarts) to do so. + +#### Verify your domain name (optional) + +If you verify a domain you get the benefit that your organisations users can use this domain as the **preferred logonname**. You find a more detailed explanation on [how ZITADEL handles usernames](administrate#How_ZITADEL_handles_usernames) here. +The verification process is documented [here](administrate#Verify_a_domain_name) + +#### Elect Managers + +ZITADEL allows you to give other users control over ZITADEL Console itself. This can be restricted to some kind of write and/or read. This can be especially useful for directing administration over several users. You can have managers able to edit project settings and others able to create/add users only. +Read the [administration](administrate#ZITADEL_Roles) guide for more information. + +> Note: ZITADEL Managers are always located on the right sidepanel of console. + +#### Integrating an application + +After creating your project you can start integrating your applications. +After choosing your [project](https://console.zitadel.ch/projects) add a client application on the top of the page. +The wizard should provide some guidance what client is the proper for you. If you are still unsure consult our [Quickstart Guides](quickstarts). diff --git a/site/docs/start/02-orbos.md b/site/docs/start/02-orbos.md new file mode 100644 index 000000000..e7f23c529 --- /dev/null +++ b/site/docs/start/02-orbos.md @@ -0,0 +1,7 @@ +--- +title: ORBOS +--- + +### Use ORBOS to install ZITADEL + +> This will be added later on \ No newline at end of file diff --git a/site/docs/start/03-static-manifest.md b/site/docs/start/03-static-manifest.md new file mode 100644 index 000000000..feefa24eb --- /dev/null +++ b/site/docs/start/03-static-manifest.md @@ -0,0 +1,7 @@ +--- +title: Static Manifest +--- + +### Install ZITADEL with static manifest + +> This will be added later on diff --git a/site/docs/use/00-user.de.md b/site/docs/use/00-user.de.md deleted file mode 100644 index 2fee90e9d..000000000 --- a/site/docs/use/00-user.de.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Benutzerhandbuch ---- - -> This Language is not yet translated. Please consult the English version. diff --git a/site/docs/use/00-user.en.md b/site/docs/use/00-user.md similarity index 94% rename from site/docs/use/00-user.en.md rename to site/docs/use/00-user.md index 3e96eae4f..e429fe62d 100644 --- a/site/docs/use/00-user.en.md +++ b/site/docs/use/00-user.md @@ -2,6 +2,8 @@ title: User Manual --- + + > All documentations are under active work and subject to change soon! ### Self Register User diff --git a/site/docs/vue/00-overview.md b/site/docs/vue/00-overview.md new file mode 100644 index 000000000..ee5ab402c --- /dev/null +++ b/site/docs/vue/00-overview.md @@ -0,0 +1,15 @@ +--- +title: Vue Login and User Endpoint +description: ... +--- + +
+ zitadel + + vue +
+ + +> This quickstart is not yet released. Come back later! + +This Integration guide shows you the recommended way on how to integrate **ZITADEL** into your Vue Frontend Application. diff --git a/site/package-lock.json b/site/package-lock.json index b30c52905..175d547d4 100644 --- a/site/package-lock.json +++ b/site/package-lock.json @@ -1187,14 +1187,6 @@ "to-fast-properties": "^2.0.0" } }, - "@formatjs/ecma402-abstract": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.5.0.tgz", - "integrity": "sha512-wXv36yo+mfWllweN0Fq7sUs7PUiNopn7I0JpLTe3hGu6ZMR4CV7LqK1llhB18pndwpKoafQKb1et2DCJAOW20Q==", - "requires": { - "tslib": "^2.0.1" - } - }, "@polka/send": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/@polka/send/-/send-0.4.0.tgz", @@ -1206,9 +1198,9 @@ "integrity": "sha512-oZLYFEAzUKyi3SKnXvj32ZCEGH6RDnao7COuCVhDydMS9NrCSVXhM79VaKyP5+Zc33m0QXEd2DN3UkU7OsHcfw==" }, "@rollup/plugin-babel": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.2.2.tgz", - "integrity": "sha512-MjmH7GvFT4TW8xFdIeFS3wqIX646y5tACdxkTO+khbHvS3ZcVJL6vkAHLw2wqPmkhwCfWHoNsp15VYNwW6JEJA==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.2.3.tgz", + "integrity": "sha512-DOMc7nx6y5xFi86AotrFssQqCen6CxYn+zts5KSI879d4n1hggSb4TH3mjVgG17Vc3lZziWWfcXzrEmVdzPMdw==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.10.4", @@ -1216,9 +1208,9 @@ } }, "@rollup/plugin-commonjs": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-17.0.0.tgz", - "integrity": "sha512-/omBIJG1nHQc+bgkYDuLpb/V08QyutP9amOrJRUSlYJZP+b/68gM//D8sxJe3Yry2QnYIr3QjR3x4AlxJEN3GA==", + "version": "17.1.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-17.1.0.tgz", + "integrity": "sha512-PoMdXCw0ZyvjpCMT5aV4nkL0QywxP29sODQsSGeDpr/oI49Qq9tRtAsb/LbYbDzFlOydVEqHmmZWFtXJEAX9ew==", "dev": true, "requires": { "@rollup/pluginutils": "^3.1.0", @@ -1240,9 +1232,9 @@ } }, "@rollup/plugin-node-resolve": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.0.1.tgz", - "integrity": "sha512-ltlsj/4Bhwwhb+Nb5xCz/6vieuEj2/BAkkqVIKmZwC7pIdl8srmgmglE4S0jFlZa32K4qvdQ6NHdmpRKD/LwoQ==", + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.1.1.tgz", + "integrity": "sha512-zlBXR4eRS+2m79TsUZWhsd0slrHUYdRx4JF+aVQm+MI0wsKdlpC2vlDVjmlGvtZY1vsefOT9w3JxvmWSBei+Lg==", "dev": true, "requires": { "@rollup/pluginutils": "^3.1.0", @@ -1284,17 +1276,6 @@ "magic-string": "^0.25.7" } }, - "@rollup/plugin-url": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-url/-/plugin-url-6.0.0.tgz", - "integrity": "sha512-UHGyoo3EbLufCZtXon/baNf75PAYT+Gs/NUgFMx2ZaDQ314PKNP0pJTrpbhDqFkZADzpkqJWyQOfJ2Nd6Qk4TA==", - "dev": true, - "requires": { - "@rollup/pluginutils": "^3.1.0", - "make-dir": "^3.1.0", - "mime": "^2.4.6" - } - }, "@rollup/pluginutils": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", @@ -1495,6 +1476,17 @@ } } }, + "clipboard": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.6.tgz", + "integrity": "sha512-g5zbiixBRk/wyKakSwCKd7vQXDjFnAMGHoEyBogG/bw9kTD9GvdAvaoRR1ALcEzt3pVKxZR0pViekPMIS0QyGg==", + "optional": true, + "requires": { + "good-listener": "^1.2.2", + "select": "^1.1.2", + "tiny-emitter": "^2.0.0" + } + }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -1516,6 +1508,12 @@ "integrity": "sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw==", "dev": true }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, "commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", @@ -1601,7 +1599,8 @@ "deepmerge": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==" + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true }, "define-properties": { "version": "1.1.3", @@ -1612,10 +1611,11 @@ "object-keys": "^1.0.12" } }, - "dlv": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", - "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" + "delegate": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz", + "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==", + "optional": true }, "electron-to-chromium": { "version": "1.3.633", @@ -1674,9 +1674,10 @@ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" }, "estree-walker": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.1.tgz", - "integrity": "sha512-tF0hv+Yi2Ot1cwj9eYHtxC0jB9bmjacjQs6ZBTj82H8JwUywFuc+7E83NWfNMwHXZc11mjfFcVXPe9gEP4B8dg==" + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true }, "esutils": { "version": "2.0.3", @@ -1684,11 +1685,6 @@ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, - "fast-memoize": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/fast-memoize/-/fast-memoize-2.5.2.tgz", - "integrity": "sha512-Ue0LwpDYErFbmNnZSF0UH6eImUwDmogUO1jyE+JbN2gsQz/jICm1Ve7t9QT0rNSsfJt+Hs4/S3GnsDVjL4HVrw==" - }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -1696,9 +1692,9 @@ "dev": true }, "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.1.tgz", + "integrity": "sha512-YR47Eg4hChJGAB1O3yEAOkGO+rlzutoICGqGo9EZ4lKWokzZRSyIW1QmTzqjtw8MJdj9srP869CuWw/hyzSiBw==", "dev": true, "optional": true }, @@ -1745,21 +1741,20 @@ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true }, - "globalyzer": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz", - "integrity": "sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==" - }, - "globrex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", - "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==" - }, "golden-fleece": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/golden-fleece/-/golden-fleece-1.0.9.tgz", "integrity": "sha512-YSwLaGMOgSBx9roJlNLL12c+FRiw7VECphinc6mGucphc/ZxTHgdEz6gmJqH6NOzYEd/yr64hwjom5pZ+tJVpg==" }, + "good-listener": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz", + "integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=", + "optional": true, + "requires": { + "delegate": "^3.1.2" + } + }, "graceful-fs": { "version": "4.2.4", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", @@ -1817,14 +1812,6 @@ "param-case": "^2.1.1", "relateurl": "^0.2.7", "uglify-js": "^3.5.1" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - } } }, "http-link-header": { @@ -1849,25 +1836,6 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "intl-messageformat": { - "version": "9.3.20", - "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-9.3.20.tgz", - "integrity": "sha512-jmpjYHE076J/0CIofrPhtUC4LfmsAhuv4JMQxytl2KJd2bim+3+gQJh+Z1vyHUzcj4fIHdt388ZGchb8f0NwOA==", - "requires": { - "fast-memoize": "^2.5.2", - "intl-messageformat-parser": "6.0.18", - "tslib": "^2.0.1" - } - }, - "intl-messageformat-parser": { - "version": "6.0.18", - "resolved": "https://registry.npmjs.org/intl-messageformat-parser/-/intl-messageformat-parser-6.0.18.tgz", - "integrity": "sha512-vLjACEunfi5uSUCWFLOR4PXQ9DGLpED3tM7o9zsYsOvjl0VIheoxyG0WZXnsnhn+S+Zu158M6CkuHXeNZfKRRg==", - "requires": { - "@formatjs/ecma402-abstract": "1.5.0", - "tslib": "^2.0.1" - } - }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -2033,27 +2001,10 @@ "sourcemap-codec": "^1.4.4" } }, - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "requires": { - "semver": "^6.0.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, "marked": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/marked/-/marked-1.2.7.tgz", - "integrity": "sha512-No11hFYcXr/zkBvL6qFmAp1z6BKY3zqLMHny/JN/ey+al7qwCM2+CMBL9BOgqMxZU36fz4cCWfn2poWIf7QRXA==" + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/marked/-/marked-1.2.8.tgz", + "integrity": "sha512-lzmFjGnzWHkmbk85q/ILZjFoHHJIQGF+SxGEfIdGk/XhiTPhqGs37gbru6Kkd48diJnEyYwnG67nru0Z2gQtuQ==" }, "matchit": { "version": "1.1.0", @@ -2076,9 +2027,9 @@ "dev": true }, "mime": { - "version": "2.4.6", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz", - "integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==" + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.0.tgz", + "integrity": "sha512-ft3WayFSFUVBuJj7BMLKAQcSlItKtfjsKDDsii3rqFDAZ7t11zRe8ASw/GlmivGwVUYtwkQrxiGGpL6gFvB0ag==" }, "mime-db": { "version": "1.44.0", @@ -2108,11 +2059,6 @@ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true }, - "mri": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/mri/-/mri-1.1.6.tgz", - "integrity": "sha512-oi1b3MfbyGa7FJMP9GmLTttni5JoICpYBRlq+x5V16fZbLsnL9N3wFqqIm/nIG43FjUFkFh9Epzp/kzUGUnJxQ==" - }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -2284,6 +2230,14 @@ "trouter": "^2.0.1" } }, + "prismjs": { + "version": "1.23.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.23.0.tgz", + "integrity": "sha512-c29LVsqOaLbBHuIbsTxaKENh1N2EQBOHaWv7gkHN4dgRbxSREqDnDbtFJYdpPauS4YCplMSNCABQ6Eeor69bAA==", + "requires": { + "clipboard": "^2.0.0" + } + }, "randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -2394,23 +2348,22 @@ } }, "rollup": { - "version": "2.35.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.35.1.tgz", - "integrity": "sha512-q5KxEyWpprAIcainhVy6HfRttD9kutQpHbeqDTWnqAFNJotiojetK6uqmcydNMymBEtC4I8bCYR+J3mTMqeaUA==", + "version": "2.38.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.38.4.tgz", + "integrity": "sha512-B0LcJhjiwKkTl79aGVF/u5KdzsH8IylVfV56Ut6c9ouWLJcUK17T83aZBetNYSnZtXf2OHD4+2PbmRW+Fp5ulg==", "dev": true, "requires": { - "fsevents": "~2.1.2" + "fsevents": "~2.3.1" } }, "rollup-plugin-svelte": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/rollup-plugin-svelte/-/rollup-plugin-svelte-6.1.1.tgz", - "integrity": "sha512-ijnm0pH1ScrY4uxwaNXBpNVejVzpL2769hIEbAlnqNUWZrffLspu5/k9/l/Wsj3NrEHLQ6wCKGagVJonyfN7ow==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-svelte/-/rollup-plugin-svelte-7.1.0.tgz", + "integrity": "sha512-vopCUq3G+25sKjwF5VilIbiY6KCuMNHP1PFvx2Vr3REBNMDllKHFZN2B9jwwC+MqNc3UPKkjXnceLPEjTjXGXg==", "dev": true, "requires": { "require-relative": "^0.8.7", - "rollup-pluginutils": "^2.8.2", - "sourcemap-codec": "^1.4.8" + "rollup-pluginutils": "^2.8.2" } }, "rollup-plugin-terser": { @@ -2442,14 +2395,6 @@ } } }, - "sade": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/sade/-/sade-1.7.4.tgz", - "integrity": "sha512-y5yauMD93rX840MwUJr7C1ysLFBgMspsdTo4UVrDg3fXDvtwOyIqykhVAAm6fk/3au77773itJStObgK+LKaiA==", - "requires": { - "mri": "^1.1.0" - } - }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -2477,6 +2422,12 @@ } } }, + "select": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz", + "integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=", + "optional": true + }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", @@ -2514,15 +2465,15 @@ "dev": true }, "shimport": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/shimport/-/shimport-2.0.4.tgz", - "integrity": "sha512-5YOyQqYkOFSkPFnpS87De6BYzDiZBc8FS4/aTuGZiST+WmXSwWRoaNRHqyVOeEpSx9wlgYWg9WYfCuzD/11/qA==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/shimport/-/shimport-2.0.5.tgz", + "integrity": "sha512-H2FeQyImK4CFhGG1wVhHEB1hASWz+WQK6t2gMP5lk+b0PW30XSrsryDONDBwF1n6hBKsmbr0REfTinaNdEkcPQ==", "dev": true }, "sirv": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/sirv/-/sirv-1.0.10.tgz", - "integrity": "sha512-H5EZCoZaggEUQy8ocKsF7WAToGuZhjJlLvM3XOef46CbdIgbNeQ1p32N1PCuCjkVYwrAVOSMacN6CXXgIzuspg==", + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-1.0.11.tgz", + "integrity": "sha512-SR36i3/LSWja7AJNRBz4fF/Xjpn7lQFI30tZ434dIy+bitLYSP+ZEenHg36i23V2SGEz+kqjksg0uOGZ5LPiqg==", "requires": { "@polka/url": "^1.0.0-next.9", "mime": "^2.3.1", @@ -2694,24 +2645,11 @@ } }, "svelte": { - "version": "3.31.0", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.31.0.tgz", - "integrity": "sha512-r+n8UJkDqoQm1b+3tA3Lh6mHXKpcfOSOuEuIo5gE2W9wQYi64RYX/qE6CZBDDsP/H4M+N426JwY7XGH4xASvGQ==", + "version": "3.32.1", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.32.1.tgz", + "integrity": "sha512-j1KmD2ZOU0RGq1/STDXjwfh0/eJ/Deh2NXyuz1bpR9eOcz9yImn4CGxXdbSAN7cMTm9a7IyPUIbuBCzu/pXK0g==", "dev": true }, - "svelte-i18n": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/svelte-i18n/-/svelte-i18n-3.3.0.tgz", - "integrity": "sha512-2pIfd4G8QfB87udPugt6g2Wl/qZ0kIB60+nQKHdon7d7aFzY5qsYT2NqQgK7dnVO2Gu0R8i2kSsNzsaVSk5UsA==", - "requires": { - "deepmerge": "^4.2.2", - "dlv": "^1.1.3", - "estree-walker": "^2.0.1", - "intl-messageformat": "^9.3.15", - "sade": "^1.7.4", - "tiny-glob": "^0.2.6" - } - }, "terser": { "version": "5.3.8", "resolved": "https://registry.npmjs.org/terser/-/terser-5.3.8.tgz", @@ -2737,14 +2675,11 @@ } } }, - "tiny-glob": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.8.tgz", - "integrity": "sha512-vkQP7qOslq63XRX9kMswlby99kyO5OvKptw7AMwBVMjXEI7Tb61eoI5DydyEMOseyGS5anDN1VPoVxEvH01q8w==", - "requires": { - "globalyzer": "0.1.0", - "globrex": "^0.1.2" - } + "tiny-emitter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", + "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==", + "optional": true }, "to-fast-properties": { "version": "2.0.0", @@ -2765,15 +2700,10 @@ "matchit": "^1.0.0" } }, - "tslib": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz", - "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==" - }, "uglify-js": { - "version": "3.11.5", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.11.5.tgz", - "integrity": "sha512-btvv/baMqe7HxP7zJSF7Uc16h1mSfuuSplT0/qdjxseesDU+yYzH33eHBH+eMdeRXwujXspaCTooWHQVVBh09w==", + "version": "3.12.6", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.12.6.tgz", + "integrity": "sha512-aqWHe3DfQmZUDGWBbabZ2eQnJlQd1fKlMUu7gV+MiTuDzdgDw31bI3wA2jLLsV/hNcDP26IfyEgSVoft5+0SVw==", "dev": true }, "unicode-canonical-property-names-ecmascript": { diff --git a/site/package.json b/site/package.json index 723238fa1..fb837018a 100644 --- a/site/package.json +++ b/site/package.json @@ -5,7 +5,7 @@ "scripts": { "dev": "sapper dev", "build": "sapper build --legacy", - "export": "sapper export --legacy", + "export": "sapper export --legacy --concurrent 1", "start": "node __sapper__/build", "cy:run": "cypress run", "cy:open": "cypress open", @@ -17,11 +17,11 @@ "@sindresorhus/slugify": "^1.1.0", "compression": "^1.7.4", "golden-fleece": "^1.0.9", - "highlight.js": "^10.3.1", - "marked": "^1.2.2", + "highlight.js": "^10.5.0", + "marked": "^1.2.8", "polka": "^0.5.2", - "svelte-i18n": "^3.1.0", - "sirv": "^1.0.7" + "prismjs": "^1.23.0", + "sirv": "^1.0.11" }, "devDependencies": { "@babel/core": "^7.12.3", @@ -29,17 +29,16 @@ "@babel/plugin-transform-runtime": "^7.9.0", "@babel/preset-env": "^7.12.1", "@babel/runtime": "^7.12.1", - "@rollup/plugin-babel": "^5.0.0", - "@rollup/plugin-commonjs": "^17.0.0", + "@rollup/plugin-babel": "^5.2.3", + "@rollup/plugin-commonjs": "^17.1.0", "@rollup/plugin-json": "^4.0.3", - "@rollup/plugin-node-resolve": "^11.0.1", + "@rollup/plugin-node-resolve": "^11.1.1", "@rollup/plugin-replace": "^2.2.0", - "@rollup/plugin-url": "^6.0.0", "npm-run-all": "^4.1.5", - "rollup": "^2.32.1", - "rollup-plugin-svelte": "^6.1.0", + "rollup": "^2.38.4", + "rollup-plugin-svelte": "^7.0.0", "rollup-plugin-terser": "^7.0.2", "sapper": "^0.28.10", - "svelte": "^3.31.0" + "svelte": "^3.32.1" } } diff --git a/site/quickstarts/000-vue.md b/site/quickstarts/000-vue.md new file mode 100644 index 000000000..783e95503 --- /dev/null +++ b/site/quickstarts/000-vue.md @@ -0,0 +1,13 @@ +--- +title: Vue +subtitle: Web Apps +img: tech/vue.svg +date: 29 January 2021 +readingtime: 5min +route: vue +visible: false +--- + +This Integration guide shows you our recommended way on how to integrate **ZITADEL** into your Vue Application. +It demonstrates how to add a user login and fetch some data from the user info endpoint. +This Guide is using our [Vue]() template app as reference \ No newline at end of file diff --git a/site/quickstarts/100-angular.md b/site/quickstarts/100-angular.md new file mode 100644 index 000000000..b304934ec --- /dev/null +++ b/site/quickstarts/100-angular.md @@ -0,0 +1,13 @@ +--- +title: Angular +subtitle: Web Apps +img: tech/angular.svg +date: 29 January 2021 +readingtime: 6min +route: angular +visible: true +--- + + +This Integration guide shows you the recommended way on how to integrate **ZITADEL** into your Angular Application. +It demonstrates how to add a user login and fetch some data from the user info endpoint. \ No newline at end of file diff --git a/site/quickstarts/200-flutter.md b/site/quickstarts/200-flutter.md new file mode 100644 index 000000000..f8840159c --- /dev/null +++ b/site/quickstarts/200-flutter.md @@ -0,0 +1,12 @@ +--- +title: Dart / Flutter +subtitle: Native Apps +img: tech/flutter.svg +date: 29 January 2021 +readingtime: 15min +route: flutter +visible: false +--- + +This Integration guide shows you the recommended way on how to integrate **ZITADEL** into your Flutter Application. +This guide is using the Flutter framework and contains additional info on how to configure Android as well as IOS Apps. \ No newline at end of file diff --git a/site/quickstarts/300-go.md b/site/quickstarts/300-go.md new file mode 100644 index 000000000..8dfde8556 --- /dev/null +++ b/site/quickstarts/300-go.md @@ -0,0 +1,12 @@ +--- +title: Go +subtitle: Backend +img: tech/golang.svg +date: 29 January 2021 +readingtime: 5min +route: go +visible: true +--- + + +This Integration guide shows you the recommended way on how to integrate **ZITADEL** into your Go Backend. diff --git a/site/quickstarts/400-aspnet.md b/site/quickstarts/400-aspnet.md new file mode 100644 index 000000000..96e50ac5e --- /dev/null +++ b/site/quickstarts/400-aspnet.md @@ -0,0 +1,12 @@ +--- +title: ASP.NET +subtitle: Backend +img: tech/net.svg +date: 29 January 2021 +readingtime: 5min +route: aspnet +visible: true +--- + +This Integration guide shows you how to access **ZITADEL** for authentication and authorization in your ASP.NET Backend. +This Guide is based on our [ZITADEL NET](https://github.com/caos/zitadel-net) Library. diff --git a/site/quickstarts/500-OAuth2-Proxy.md b/site/quickstarts/500-OAuth2-Proxy.md new file mode 100644 index 000000000..0d48f73df --- /dev/null +++ b/site/quickstarts/500-OAuth2-Proxy.md @@ -0,0 +1,11 @@ +--- +title: OAuth2 Proxy +subtitle: Proxy +img: tech/oauth2-proxy.svg +date: 08 February 2021 +readingtime: 3min +route: oauth2-proxy +visible: true +--- + +With this quickstart you will learn how to use a OAuth 2.0 Proxy in conjuction with **ZITADEL**. \ No newline at end of file diff --git a/site/rollup.config.js b/site/rollup.config.js index 418d18cdc..1c9969307 100644 --- a/site/rollup.config.js +++ b/site/rollup.config.js @@ -1,3 +1,4 @@ +// eslint-disable-next-line import/no-named-as-default import babel from '@rollup/plugin-babel'; import commonjs from '@rollup/plugin-commonjs'; import json from '@rollup/plugin-json'; @@ -13,20 +14,10 @@ const mode = process.env.NODE_ENV; const dev = mode === 'development'; const legacy = !!process.env.SAPPER_LEGACY_BUILD; -const onwarn = (warning, onwarn) => { - if ( - (warning.code === 'CIRCULAR_DEPENDENCY' && - /[/\\]@sapper[/\\]/.test(warning.message)) - ) { - return; - } - - if (warning.code === 'THIS_IS_UNDEFINED') { - return; - } - +const onwarn = (warning, onwarn) => + (warning.code === 'MISSING_EXPORT' && /'preload'/.test(warning.message)) || + (warning.code === 'CIRCULAR_DEPENDENCY' && /[/\\]@sapper[/\\]/.test(warning.message)) || onwarn(warning); -}; export default { client: { @@ -38,9 +29,10 @@ export default { 'process.env.NODE_ENV': JSON.stringify(mode) }), svelte({ - dev, - hydratable: true, - emitCss: true + compilerOptions: { + dev, + hydratable: true + } }), resolve({ browser: true, @@ -68,11 +60,11 @@ export default { !dev && terser({ module: true }), - json() ], + preserveEntrySignatures: false, - onwarn, + onwarn }, server: { @@ -84,8 +76,12 @@ export default { 'process.env.NODE_ENV': JSON.stringify(mode) }), svelte({ - generate: 'ssr', - dev + compilerOptions: { + dev, + generate: 'ssr', + hydratable: true + }, + emitCss: false }), resolve({ dedupe: ['svelte'] @@ -96,8 +92,9 @@ export default { external: Object.keys(pkg.dependencies).concat( require('module').builtinModules || Object.keys(process.binding('natives')) ), + preserveEntrySignatures: 'strict', - onwarn, + onwarn }, serviceworker: { @@ -110,9 +107,11 @@ export default { 'process.env.NODE_ENV': JSON.stringify(mode) }), commonjs(), + // json(), !dev && terser() ], + preserveEntrySignatures: false, - onwarn, - }, -}; + onwarn + } +}; \ No newline at end of file diff --git a/site/src/client.js b/site/src/client.js index fb03b5816..3964c2e1c 100644 --- a/site/src/client.js +++ b/site/src/client.js @@ -2,13 +2,6 @@ import '../static/base.css'; import * as sapper from '@sapper/app'; -import { startClient } from './i18n.js'; -import { initPhotoSwipeFromDOM } from './utils/photoswipe.js'; - -startClient(); - -initPhotoSwipeFromDOM('.zitadel-gallery'); - sapper.start({ target: document.querySelector('#sapper') -}); +}); \ No newline at end of file diff --git a/site/src/components/CodeTable.svelte b/site/src/components/CodeTable.svelte deleted file mode 100644 index 3ad524cdd..000000000 --- a/site/src/components/CodeTable.svelte +++ /dev/null @@ -1,121 +0,0 @@ - - - - -
- - - - -
- {#each tabs as { lang, content }, i} -
- {content} -
- {/each} -
-
diff --git a/site/src/components/Docs.svelte b/site/src/components/Docs.svelte index e1b6bf5fb..d2b000fed 100644 --- a/site/src/components/Docs.svelte +++ b/site/src/components/Docs.svelte @@ -1,8 +1,7 @@ - - - -
- zitadel logo - - -
- - -
- - More about ZITADEL - -
- -{#if menuOpen} - -{/if} \ No newline at end of file diff --git a/site/src/components/GuideContents.svelte b/site/src/components/GuideContents.svelte index f0eb4157a..9ad418312 100644 --- a/site/src/components/GuideContents.svelte +++ b/site/src/components/GuideContents.svelte @@ -1,8 +1,7 @@ - - - - - -
- {#each LANGUAGES as lang} - - {/each} -
diff --git a/site/src/components/Nav.svelte b/site/src/components/Nav.svelte index 7a3486076..afbffed6b 100644 --- a/site/src/components/Nav.svelte +++ b/site/src/components/Nav.svelte @@ -1,17 +1,28 @@ {#if external} - +
  • {:else} - + {#if prefetch} +
  • + {:else} +
  • + {/if} {/if} \ No newline at end of file diff --git a/site/src/components/SearchSelector.svelte b/site/src/components/SearchSelector.svelte index 84dc42b05..daf89ecfa 100644 --- a/site/src/components/SearchSelector.svelte +++ b/site/src/components/SearchSelector.svelte @@ -1,6 +1,5 @@ + +
    -
    + + \ No newline at end of file diff --git a/site/src/routes/index.svelte b/site/src/routes/index.svelte index 3d38b0175..8aa75e857 100644 --- a/site/src/routes/index.svelte +++ b/site/src/routes/index.svelte @@ -1,33 +1,11 @@ - - @@ -193,165 +149,124 @@ ZITADEL • Documentation - {$_('title')} - + ZITADEL • Documentation + - - + + - - + + - -
    -
    - -

    {$_('languagealsoavailable')}: - {#each LANGUAGES as lang} - {#if lang != $locale} - {lang == 'de'? 'Deutsch (WIP)' : 'English'} - {/if} - {/each} -

    -
    -

    {$_('title')}

    -

    {$_('description')}

    -

    {$_('description2')}

    -

    {$_('description3')}

    +

    ZITADEL Identity and Access Management

    +

    Most applications need to know the identity of a user allowing to securely store user data in the cloud and provide the same personalised experience across all of the user's devices.

    +

    ZITADEL's authentication provides backend services, easy-to-use SDKs, and ready-made UI libraries to authenticate users in your application. It supports authentication using passwords and applies additional security with the help of a second factor, for example OTP, to ensure a safe and secure access.

    +

    ZITADEL's authentication leverages industry standards like OAuth 2.0 and OpenID Connect so that it can be easily integrated in your custom backend.

    caos logo
    -

    {$_('startlink')}

    -

    {$_('startlink_desc')}

    +

    Follow this guide to get started with ZITADEL in general.

    - - - {#if $locale == 'en'} - - {:else if $locale == 'de'} - - {/if}
    -

    {$_('integratelink')}

    -

    {$_('integratelink_desc')}

    - {$_('learnmore')} +

    Quickstarts

    +

    Learn how to integrate your applications and build secure workflows and APIs with ZITADEL

    - {#if $locale == 'en'} -

    {$_('inthissection')}

    - - {/if} +
    + react + angular + flutter + golang + aspnet +
    + Learn more + +

    In this section

    +
    - Develop
    -

    {$_('administratelink')}

    -

    {$_('administratelink_desc')}

    - {$_('learnmore')} +

    Administration

    +

    Learn how to manage your data and role associations in ZITADEL

    + Learn more -

    {$_('inthissection')}

    +

    In this section

    - {#if $locale == 'en'} - - {:else if $locale == 'de'} - - {/if} -
    - Develop -
    - -
    -
    -

    {$_('developlink')}

    -

    {$_('developlink_desc')}

    - {$_('learnmore')} - -

    {$_('inthissection')}

    - - {#if $locale == 'en'} - - {:else if $locale == 'de'} - - {/if} +
    -

    {$_('docslink')}

    -

    {$_('docslink_desc')}

    - {$_('learnmore')} +

    APIs

    + +

    Learn more about our APIs and how to integrate them in your apps.

    + Learn more -

    {$_('inthissection')}

    - {#if $locale == 'en'} - - {:else if $locale == 'de'} - - {/if} +

    In this section

    + +
    -

    {$_('uselink')}

    -

    {$_('uselink_desc')}

    - {$_('learnmore')} -
    +

    Architecture and Technologies

    + +

    Learn more about engineering and design principles, ZITADELs architecture and used technologies.

    + Learn more - Develop +

    In this section

    + +
    +
    + +
    +
    +

    User Manuals

    + + +

    Follow this guide to get started with ZITADEL as a user.

    + Learn more +
    diff --git a/site/src/routes/quickstarts/_quickstarts.js b/site/src/routes/quickstarts/_quickstarts.js new file mode 100644 index 000000000..350f64f69 --- /dev/null +++ b/site/src/routes/quickstarts/_quickstarts.js @@ -0,0 +1,59 @@ +import fs from 'fs'; +import marked from 'marked'; +import path from 'path'; + +import { SLUG_PRESERVE_UNICODE } from '../../../config'; +import { highlight } from '../../utils/highlight'; +import { extract_frontmatter, link_renderer } from '../../utils/markdown.js'; +import { makeSlugProcessor } from '../../utils/slug'; + +const makeSlug = makeSlugProcessor(SLUG_PRESERVE_UNICODE); + +export default function get_quickstarts() { + return fs + .readdirSync('quickstarts') + .map(file => { + if (path.extname(file) !== '.md') return; + + const match = /^([0-9]+)-(.+)\.md$/.exec(file); + if (!match) throw new Error(`Invalid filename '${file}'`); + + const [, order, slug] = match; + + const markdown = fs.readFileSync(`quickstarts/${file}`, 'utf-8'); + + const { content, metadata } = extract_frontmatter(markdown); + + const renderer = new marked.Renderer(); + + renderer.link = link_renderer; + + renderer.code = highlight; + + renderer.heading = (text, level, rawtext) => { + const fragment = makeSlug(rawtext); + + return ` + + + + ${text} + `; + }; + + const answer = marked( + content.replace(/^\t+/gm, match => match.split('\t').join(' ')), + { renderer } + ); + + const fragment = makeSlug(slug); + + return { + fragment, + order, + answer, + metadata + }; + }) + .sort((a, b) => a.order - b.order); +} \ No newline at end of file diff --git a/site/src/routes/quickstarts/index.json.js b/site/src/routes/quickstarts/index.json.js new file mode 100644 index 000000000..5faf96cf7 --- /dev/null +++ b/site/src/routes/quickstarts/index.json.js @@ -0,0 +1,25 @@ +import send from '@polka/send'; + +import get_quickstarts from './_quickstarts.js'; + +let json; + +export function get(req, res) { + if (!json || process.env.NODE_ENV !== 'production') { + const qss = get_quickstarts() + .map(qs => { + return { + fragment: qs.fragment, + answer: qs.answer, + metadata: qs.metadata + }; + }); + + json = JSON.stringify(qss); + } + + send(res, 200, json, { + 'Content-Type': 'application/json', + 'Cache-Control': `max-age=${5 * 60 * 1e3}` // 5 minutes + }); +} \ No newline at end of file diff --git a/site/src/routes/quickstarts/index.svelte b/site/src/routes/quickstarts/index.svelte new file mode 100644 index 000000000..f0c30fe92 --- /dev/null +++ b/site/src/routes/quickstarts/index.svelte @@ -0,0 +1,154 @@ + + + + + + Quickstarts ZITADEL + + + + + + +
    +

    Quickstarts ZITADEL

    + {#each qss as qs} + {#if qs.metadata.visible == 'true'} +
    +
    +

    {qs.metadata.subtitle}

    +

    + + + {qs.metadata.title} +

    +

    {@html qs.answer}

    + Read Quickstart +

    {qs.metadata.date} • {qs.metadata.readingtime}

    +
    + article img +
    + {/if} + {/each} +

    See also our Github page ZITADEL for questions regarding the sourcecode.

    + + \ No newline at end of file diff --git a/site/src/server.js b/site/src/server.js index e874066b4..d0e4e1d61 100644 --- a/site/src/server.js +++ b/site/src/server.js @@ -3,8 +3,6 @@ import compression from 'compression'; import polka from 'polka'; import sirv from 'sirv'; -import { i18nMiddleware } from './i18n.js'; - const { PORT, NODE_ENV } = process.env; const dev = NODE_ENV === 'development'; @@ -12,7 +10,6 @@ polka() .use( compression({ threshold: 0 }), sirv('static', { dev }), - i18nMiddleware(), sapper.middleware() ) .listen(PORT, err => { diff --git a/site/src/service-worker.js b/site/src/service-worker.js index 54c62e271..fad33e525 100644 --- a/site/src/service-worker.js +++ b/site/src/service-worker.js @@ -1,5 +1,6 @@ -import { files, routes, shell, timestamp } from '@sapper/service-worker'; +import { files, shell, timestamp } from '@sapper/service-worker'; +// eslint-disable-next-line import/no-unresolved const ASSETS = `cache${timestamp}`; // `shell` is an array of all the files generated by the bundler, @@ -51,12 +52,12 @@ self.addEventListener('fetch', event => { // for pages, you might want to serve a shell `service-worker-index.html` file, // which Sapper has generated for you. It's not right for every // app, but if it's right for yours then uncomment this section - - // if (url.origin === self.origin && routes.find(route => route.pattern.test(url.pathname))) { - // event.respondWith(caches.match('/service-worker-index.html')); - // return; - // } - + /* + if (url.origin === self.origin && routes.find(route => route.pattern.test(url.pathname))) { + event.respondWith(caches.match('/service-worker-index.html')); + return; + } + */ if (event.request.cache === 'only-if-cached') return; @@ -79,4 +80,4 @@ self.addEventListener('fetch', event => { } }) ); -}); +}); \ No newline at end of file diff --git a/site/src/template.html b/site/src/template.html index 86f49fa5d..8da09bfbf 100644 --- a/site/src/template.html +++ b/site/src/template.html @@ -98,7 +98,7 @@ + initialise the router --> %sapper.scripts% diff --git a/site/src/utils/generate_code_tabs.js b/site/src/utils/generate_code_tabs.js deleted file mode 100644 index d404310ab..000000000 --- a/site/src/utils/generate_code_tabs.js +++ /dev/null @@ -1,3 +0,0 @@ -export default function generate_code_tabs(dirpath, dir) { - -} \ No newline at end of file diff --git a/site/src/utils/generate_docs.js b/site/src/utils/generate_docs.js index 572507dae..739801951 100644 --- a/site/src/utils/generate_docs.js +++ b/site/src/utils/generate_docs.js @@ -20,18 +20,16 @@ const block_types = [ 'tablecell' ]; -export default function generate_docs(dirpath, dir, lang) { +export default function generate_docs(dirpath, dir) { const make_slug = make_session_slug_processor({ separator: SLUG_SEPARATOR, preserve_unicode: SLUG_PRESERVE_UNICODE }); - console.log('using language: ' + lang); - return fs .readdirSync(`${dirpath}${dir}`) .filter((file) => { - return file[0] !== '.' && path.extname(file) === '.md' && file.endsWith(`.${lang}.md`); + return file[0] !== '.' && path.extname(file) === '.md' && file.endsWith(`.md`); }) .map((file) => { const markdown = fs.readFileSync(`${dirpath}${dir}/${file}`, 'utf-8'); @@ -45,7 +43,7 @@ export default function generate_docs(dirpath, dir, lang) { renderer.link = link_renderer; - renderer.hr = (str) => { + renderer.hr = () => { block_open = true; return '
    '; @@ -65,7 +63,9 @@ export default function generate_docs(dirpath, dir, lang) { }; renderer.code = (source, lang) => { - source = source.replace(/^ +/gm, (match) => match.split(' ').join('\t')); + source = source.replace(/^ +/gm, match => + match.split(' ').join('\t') + ); const lines = source.split('\n'); @@ -90,6 +90,11 @@ export default function generate_docs(dirpath, dir, lang) { const plang = langs[lang]; const { value: highlighted } = hljs.highlight(lang, source); + // const highlighted = PrismJS.highlight( + // source, + // PrismJS.languages[plang], + // lang + // ); const html = `
    ${prefix}
    ${highlighted}
    `; @@ -101,16 +106,17 @@ export default function generate_docs(dirpath, dir, lang) { return html; }; - // const slugger = new marked.Slugger(); renderer.heading = (text, level, rawtext) => { const slug = level <= 4 && make_slug(rawtext); if (level === 3 || level === 4) { - const title = text.replace(/<\/?code>/g, '').replace(/\.(\w+)(\((.+)?\))?/, (m, $1, $2, $3) => { - if ($3) return `.${$1}(...)`; - if ($2) return `.${$1}()`; - return `.${$1}`; - }); + const title = text + .replace(/<\/?code>/g, '') + .replace(/\.(\w+)(\((.+)?\))?/, (m, $1, $2, $3) => { + if ($3) return `.${$1}(...)`; + if ($2) return `.${$1}()`; + return `.${$1}`; + }); subsections.push({ slug, title, level }); } @@ -118,12 +124,12 @@ export default function generate_docs(dirpath, dir, lang) { return ` 4 ? 'data-scrollignore' : ''}> - + ${text} `; }; - block_types.forEach((type) => { + block_types.forEach(type => { const fn = renderer[type]; renderer[type] = function () { return fn.apply(this, arguments); @@ -141,4 +147,4 @@ export default function generate_docs(dirpath, dir, lang) { file }; }); -} +} \ No newline at end of file diff --git a/site/src/utils/generate_seo.js b/site/src/utils/generate_seo.js index 5663f4110..d7490fc3d 100644 --- a/site/src/utils/generate_seo.js +++ b/site/src/utils/generate_seo.js @@ -1,8 +1,8 @@ import fs from 'fs'; -export default function generate_docs(dirpath, dir, lang) { +export default function generate_seo(dirpath, dir) { try { - return fs.readFileSync(`${dirpath}${dir}/seo_${lang}.html`, 'utf-8'); + return fs.readFileSync(`${dirpath}${dir}/seo.html`, 'utf-8'); } catch (error) { return ''; } diff --git a/site/src/utils/highlight.js b/site/src/utils/highlight.js new file mode 100644 index 000000000..21e803d5c --- /dev/null +++ b/site/src/utils/highlight.js @@ -0,0 +1,16 @@ +import 'prismjs/components/prism-bash'; + +import PrismJS from 'prismjs'; + +import { langs } from './markdown.js'; + +export function highlight(source, lang) { + const plang = langs[lang] || ''; + const highlighted = plang ? PrismJS.highlight( + source, + PrismJS.languages[plang], + lang + ) : source.replace(/[&<>]/g, c => ({ '&': '&', '<': '<', '>': '>' })[c]); + + return `
    ${highlighted}
    `; +} \ No newline at end of file diff --git a/site/src/utils/language_extractor.js b/site/src/utils/language_extractor.js deleted file mode 100644 index c561ff02f..000000000 --- a/site/src/utils/language_extractor.js +++ /dev/null @@ -1,21 +0,0 @@ -import fs from 'fs'; -import path from 'path'; - -export default function extract_languages(dirpath, dir) { - - const detectedLocales = fs.readdirSync(`${dirpath}${dir}`) - .filter(file => path.extname(file) == '.md') - .map((file) => { - file = file.replace(path.extname(file), ''); - const arr = file.split('.'); - const locale = arr.length ? arr[arr.length - 1] : null; - if (locale) { - return locale; - } - }).filter(locale => locale !== null); - - const redDetectedLocales = [...new Set(detectedLocales)]; - - console.log('detected locales: ' + redDetectedLocales); - return redDetectedLocales; -} diff --git a/site/src/utils/photoswipe.js b/site/src/utils/photoswipe.js index 191d7eaaa..02a7f5266 100644 --- a/site/src/utils/photoswipe.js +++ b/site/src/utils/photoswipe.js @@ -22,7 +22,8 @@ export function initPhotoSwipeFromDOM(gallerySelector) { linkEl = figureEl.children[0]; // element - size = linkEl.getAttribute('data-size').split('x'); + const dataSize = linkEl.getAttribute('data-size'); + size = dataSize ? dataSize.split('x') : '1920x1080'.split('x'); // create slide object item = { diff --git a/site/src/utils/slug.js b/site/src/utils/slug.js index e68511b4a..65bf10360 100644 --- a/site/src/utils/slug.js +++ b/site/src/utils/slug.js @@ -1,68 +1,66 @@ import slugify from '@sindresorhus/slugify'; -export const SLUG_PRESERVE_UNICODE = false; -export const SLUG_SEPARATOR = '_'; +import { SLUG_SEPARATOR } from '../../config'; /* url-safe processor */ -export const urlsafeSlugProcessor = (string, opts) => { - const { separator = SLUG_SEPARATOR } = opts || {}; - - return slugify(string, { - customReplacements: [ - // runs before any other transformations +export const urlsafeSlugProcessor = string => + slugify(string, { + customReplacements: [ // runs before any other transformations ['$', 'DOLLAR'], // `$destroy` & co ['-', 'DASH'] // conflicts with `separator` ], - separator, + separator: SLUG_SEPARATOR, decamelize: false, lowercase: false }) .replace(/DOLLAR/g, '$') .replace(/DASH/g, '-'); -}; /* unicode-preserver processor */ const alphaNumRegex = /[a-zA-Z0-9]/; const unicodeRegex = /\p{Letter}/u; -const isNonAlphaNumUnicode = (string) => !alphaNumRegex.test(string) && unicodeRegex.test(string); +const isNonAlphaNumUnicode = + string => !alphaNumRegex.test(string) && unicodeRegex.test(string); -export const unicodeSafeProcessor = (string, opts) => { - const { separator = SLUG_SEPARATOR } = opts || {}; +export const unicodeSafeProcessor = string => + string.split('') + .reduce((accum, char, index, array) => { + const type = isNonAlphaNumUnicode(char) ? 'pass' : 'process'; - return string - .split('') - .reduce( - (accum, char, index, array) => { - const type = isNonAlphaNumUnicode(char) ? 'pass' : 'process'; + if (index === 0) { + accum.current = { type, string: char }; + } else if (type === accum.current.type) { + accum.current.string += char; + } else { + accum.chunks.push(accum.current); + accum.current = { type, string: char }; + } - if (index === 0) { - accum.current = { type, string: char }; - } else if (type === accum.current.type) { - accum.current.string += char; - } else { - accum.chunks.push(accum.current); - accum.current = { type, string: char }; - } + if (index === array.length - 1) { + accum.chunks.push(accum.current); + } - if (index === array.length - 1) { - accum.chunks.push(accum.current); - } - - return accum; - }, - { chunks: [], current: { type: '', string: '' } } - ) - .chunks.reduce((accum, chunk) => { - const processed = chunk.type === 'process' ? urlsafeSlugProcessor(chunk.string) : chunk.string; + return accum; + }, { chunks: [], current: { type: '', string: '' } }) + .chunks + .reduce((accum, chunk) => { + const processed = chunk.type === 'process' + ? urlsafeSlugProcessor(chunk.string) + : chunk.string; processed.length > 0 && accum.push(processed); return accum; }, []) - .join(separator); -}; + .join(SLUG_SEPARATOR); + +/* processor */ + +export const makeSlugProcessor = (preserveUnicode = false) => preserveUnicode + ? unicodeSafeProcessor + : urlsafeSlugProcessor; /* session processor */ @@ -78,7 +76,6 @@ export const make_session_slug_processor = ({ if (seen.has(slug)) throw new Error(`Duplicate slug ${slug}`); seen.add(slug); - return slug; }; }; diff --git a/site/static/base.css b/site/static/base.css index 2bd688696..4e64846c5 100644 --- a/site/static/base.css +++ b/site/static/base.css @@ -180,7 +180,8 @@ ul { .b, b, strong { - font-weight: 600; + font-weight: 600; + color: white; } tt, @@ -193,8 +194,9 @@ samp { code { position: relative; border-radius: .3em; - white-space: nowrap; - color: var(--text); + white-space: nowrap; + font-size: var(--h6); + /* color: var(--text); */ -webkit-font-smoothing: initial; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; } @@ -223,7 +225,7 @@ li:not(.white) > h2 { blockquote { position: relative; margin: 1.6rem 0 2.4rem; - padding: 2rem 2.4rem 1.8rem 2.4rem; + padding: 1rem 2.4rem 1rem 2.4rem; border-radius: var(--border-r); font-family: var(--font); max-width: var(--linemax); @@ -326,11 +328,6 @@ a:hover { color: var(--flash); } -a:hover { - padding: 0; - border-bottom: 2px solid currentColor; -} - a.no-underline { border-bottom: none; padding: 0; @@ -405,7 +402,7 @@ td, th { text-align: left; border-bottom: 1px solid #eee; - padding: 0.4rem 0.8rem 0.4rem 0; + padding: 4px 8px 4px 0; } td[align='right'] { @@ -594,10 +591,12 @@ input[type="checkbox"]:checked::after { .zitadel-gallery img { width: 100%; object-fit: contain; + border-radius: 4px; } .zitadel-gallery figure { flex-basis: 30%; object-fit: contain; margin: 5px 5px 5px 0; width: 150px; + border-radius: 4px; } diff --git a/site/static/img/accounts_org_register.png b/site/static/img/accounts_org_register.png deleted file mode 100644 index 0bf4e4a5a..000000000 Binary files a/site/static/img/accounts_org_register.png and /dev/null differ diff --git a/site/static/img/accounts_org_register_light.png b/site/static/img/accounts_org_register_light.png new file mode 100644 index 000000000..da6ba44f0 Binary files /dev/null and b/site/static/img/accounts_org_register_light.png differ diff --git a/site/static/tech/android.svg b/site/static/tech/android.svg new file mode 100644 index 000000000..3eb806f93 --- /dev/null +++ b/site/static/tech/android.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/site/static/tech/angular.svg b/site/static/tech/angular.svg new file mode 100644 index 000000000..96301efe1 --- /dev/null +++ b/site/static/tech/angular.svg @@ -0,0 +1,16 @@ + + + + + + + + + + diff --git a/site/static/tech/aspnet.png b/site/static/tech/aspnet.png new file mode 100644 index 000000000..274660b1e Binary files /dev/null and b/site/static/tech/aspnet.png differ diff --git a/site/static/tech/dart.svg b/site/static/tech/dart.svg new file mode 100644 index 000000000..bdb580ec2 --- /dev/null +++ b/site/static/tech/dart.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/site/static/tech/flutter.svg b/site/static/tech/flutter.svg new file mode 100644 index 000000000..b65f8527e --- /dev/null +++ b/site/static/tech/flutter.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/site/static/tech/golang.svg b/site/static/tech/golang.svg new file mode 100644 index 000000000..8164d5589 --- /dev/null +++ b/site/static/tech/golang.svg @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/site/static/tech/net.svg b/site/static/tech/net.svg new file mode 100644 index 000000000..2bea1985a --- /dev/null +++ b/site/static/tech/net.svg @@ -0,0 +1 @@ +layer1 \ No newline at end of file diff --git a/site/static/tech/oauth2-proxy.svg b/site/static/tech/oauth2-proxy.svg new file mode 100644 index 000000000..4df740f6d --- /dev/null +++ b/site/static/tech/oauth2-proxy.svg @@ -0,0 +1 @@ +OAuth2_Proxy_logo_v3 \ No newline at end of file diff --git a/site/static/tech/react.png b/site/static/tech/react.png new file mode 100644 index 000000000..430e213a0 Binary files /dev/null and b/site/static/tech/react.png differ diff --git a/site/static/tech/vue.svg b/site/static/tech/vue.svg new file mode 100644 index 000000000..a1d285eb2 --- /dev/null +++ b/site/static/tech/vue.svg @@ -0,0 +1,2 @@ + +
    {{ 'PROJECT.ROLE.NAME' | translate }} - {{role.name}} {{ 'APP.NAME' | translate }} + {{app.name}} {{ 'APP.OIDC.APPTYPE' | translate }} + {{'APP.OIDC.APPTYPE'+app?.oidcConfig?.applicationType | translate}}