From 7bdf72f5251feeeacf1582b3772a1a5b61268d29 Mon Sep 17 00:00:00 2001 From: Junmin Ahn Date: Fri, 14 Oct 2022 14:51:17 -0700 Subject: [PATCH 001/118] chore: update bcgov login theme style --- .../resources/theme/bcgov/login/resources/css/styles.css | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov/login/resources/css/styles.css b/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov/login/resources/css/styles.css index 72127791..5a92faac 100644 --- a/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov/login/resources/css/styles.css +++ b/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov/login/resources/css/styles.css @@ -5,6 +5,10 @@ color: #036; } +.login-pf body .login-pf-page { + padding-bottom: 60px; +} + .login-pf body .login-pf-page #kc-header { margin-bottom: 0; } @@ -82,6 +86,7 @@ top: 0; position: fixed; width: 100%; + z-index: 100; } .login-pf body > header .banner { From 7f213fe4464e7c659d2dbd195aab400e411b10e4 Mon Sep 17 00:00:00 2001 From: Jonathan Sharman Date: Mon, 17 Oct 2022 09:33:09 -0700 Subject: [PATCH 002/118] chore: bumptimeout --- helm/keycloak/values-6d70e7-prod.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helm/keycloak/values-6d70e7-prod.yaml b/helm/keycloak/values-6d70e7-prod.yaml index 638ee488..95db9508 100644 --- a/helm/keycloak/values-6d70e7-prod.yaml +++ b/helm/keycloak/values-6d70e7-prod.yaml @@ -18,7 +18,7 @@ postgres: passwordKey: password annotations: - timeout: 60s + timeout: 90s persistentLog: storageClassSize: 15Gi From 7be9326f289d09b9e96210aa274ed7c26650713f Mon Sep 17 00:00:00 2001 From: Junmin Ahn Date: Fri, 21 Oct 2022 10:31:09 -0700 Subject: [PATCH 003/118] chore: bump keycloak image version --- helm/keycloak/values-b861c7-test-4.yaml | 2 +- helm/keycloak/values-b861c7-test-5.yaml | 2 +- helm/keycloak/values-b861c7-test-6.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/helm/keycloak/values-b861c7-test-4.yaml b/helm/keycloak/values-b861c7-test-4.yaml index ef6acea2..6ae43427 100644 --- a/helm/keycloak/values-b861c7-test-4.yaml +++ b/helm/keycloak/values-b861c7-test-4.yaml @@ -2,7 +2,7 @@ replicaCount: 1 image: repository: ghcr.io/bcgov/sso - tag: 7.6.5-build.11 + tag: 7.6.5-build.12 pullPolicy: IfNotPresent rollingUpdate: diff --git a/helm/keycloak/values-b861c7-test-5.yaml b/helm/keycloak/values-b861c7-test-5.yaml index cbdc080c..4de858b6 100644 --- a/helm/keycloak/values-b861c7-test-5.yaml +++ b/helm/keycloak/values-b861c7-test-5.yaml @@ -2,7 +2,7 @@ replicaCount: 1 image: repository: ghcr.io/bcgov/sso - tag: 7.6.5-build.3 + tag: 7.6.5-build.12 pullPolicy: IfNotPresent rollingUpdate: diff --git a/helm/keycloak/values-b861c7-test-6.yaml b/helm/keycloak/values-b861c7-test-6.yaml index bbc10817..861dec40 100644 --- a/helm/keycloak/values-b861c7-test-6.yaml +++ b/helm/keycloak/values-b861c7-test-6.yaml @@ -2,7 +2,7 @@ replicaCount: 1 image: repository: ghcr.io/bcgov/sso - tag: 7.6.5-build.3 + tag: 7.6.5-build.12 pullPolicy: IfNotPresent rollingUpdate: From 7b4fa4e2dce075293fff0fff833674a9378074cf Mon Sep 17 00:00:00 2001 From: Jonathan Sharman Date: Fri, 21 Oct 2022 15:58:35 -0700 Subject: [PATCH 004/118] chore: lessBackups --- helm/backup-storage/values-3d5c3f-prod-sso-backup.yaml | 7 +++++++ .../values-6d70e7-prod-patroni-backup-storage.yaml | 7 +++++++ helm/backup-storage/values-eb75ad-prod-sso-backup.yaml | 7 +++++++ 3 files changed, 21 insertions(+) diff --git a/helm/backup-storage/values-3d5c3f-prod-sso-backup.yaml b/helm/backup-storage/values-3d5c3f-prod-sso-backup.yaml index f5534162..550e4c31 100644 --- a/helm/backup-storage/values-3d5c3f-prod-sso-backup.yaml +++ b/helm/backup-storage/values-3d5c3f-prod-sso-backup.yaml @@ -23,3 +23,10 @@ env: TABLE_SCHEMA: value: "public" + + DAILY_BACKUPS: + value: "7" + WEEKLY_BACKUPS: + value: "4" + MONTHLY_BACKUPS: + value: "1" diff --git a/helm/backup-storage/values-6d70e7-prod-patroni-backup-storage.yaml b/helm/backup-storage/values-6d70e7-prod-patroni-backup-storage.yaml index c1d22de3..2bfc0146 100644 --- a/helm/backup-storage/values-6d70e7-prod-patroni-backup-storage.yaml +++ b/helm/backup-storage/values-6d70e7-prod-patroni-backup-storage.yaml @@ -35,3 +35,10 @@ env: TABLE_SCHEMA: value: "public" + + DAILY_BACKUPS: + value: "7" + WEEKLY_BACKUPS: + value: "4" + MONTHLY_BACKUPS: + value: "1" diff --git a/helm/backup-storage/values-eb75ad-prod-sso-backup.yaml b/helm/backup-storage/values-eb75ad-prod-sso-backup.yaml index 17e0f7c1..da5db328 100644 --- a/helm/backup-storage/values-eb75ad-prod-sso-backup.yaml +++ b/helm/backup-storage/values-eb75ad-prod-sso-backup.yaml @@ -23,3 +23,10 @@ env: WEBHOOK_URL: value: <> secure: true + + DAILY_BACKUPS: + value: "7" + WEEKLY_BACKUPS: + value: "4" + MONTHLY_BACKUPS: + value: "1" From 3529147f029ae77714414c6ea237bbc62f771a29 Mon Sep 17 00:00:00 2001 From: Junmin Ahn Date: Mon, 24 Oct 2022 11:29:35 -0700 Subject: [PATCH 005/118] feat: add a script to migrate github users from silver to gold --- ...grate-github-users-to-parent-realm-gold.js | 111 ++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 scripts/keycloak-migrate-github-users-to-parent-realm-gold.js diff --git a/scripts/keycloak-migrate-github-users-to-parent-realm-gold.js b/scripts/keycloak-migrate-github-users-to-parent-realm-gold.js new file mode 100644 index 00000000..95fb4023 --- /dev/null +++ b/scripts/keycloak-migrate-github-users-to-parent-realm-gold.js @@ -0,0 +1,111 @@ +const axios = require('axios'); +const _ = require('lodash'); +const { argv } = require('yargs'); +const Confirm = require('prompt-confirm'); +const { getAdminClient } = require('./keycloak-core'); +const { handleError, ignoreError } = require('./helpers'); +const { baseEnv, targetEnv, auto, del } = argv; + +const SILVER_GITHUB_REALM = '_github'; +const GOLD_GITHUB_REALM = 'github'; + +const fetchGithubId = async (username) => { + try { + const { id: github_id } = await axios.get(`https://api.github.com/users/${username}`).then((res) => res.data); + return github_id; + } catch { + return null; + } +}; + +// this script helps migrate users from one realm to another one including IDP links +async function main() { + if (!baseEnv || !targetEnv) { + console.info(` + Usages: + node keycloak-migrate-github-users-to-parent-realm-gold --base-env --target-env [--auto] [--del] + `); + + return; + } + + try { + const baseClient = await getAdminClient(baseEnv, { totp: 996970 }); + const targetClient = await getAdminClient(targetEnv); + if (!baseClient || !targetClient) return; + + if (!auto) { + const prompt = new Confirm(`Are you sure to proceed?`); + const answer = await prompt.run(); + if (!answer) return; + } + + const max = 500; + let first = 2400; + let total = 0; + + while (true) { + const users = await baseClient.users.find({ realm: SILVER_GITHUB_REALM, first, max }); + + const count = users.length; + total += count; + + for (let x = 0; x < users.length; x++) { + const { id, username, attributes = {}, email, firstName, lastName } = users[x]; + let { github_id } = attributes; + if (github_id && github_id.length > 0) { + github_id = github_id[0]; + } else { + github_id = await fetchGithubId(username); + } + + if (!github_id) { + console.error(`github_id not found for user ${username}`); + total -= 1; + continue; + } + + console.log('importing github user with id: ', github_id); + + try { + const newuser = await targetClient.users.create({ + enabled: true, + realm: GOLD_GITHUB_REALM, + username: github_id, + email, + firstName, + lastName, + attributes: { + github_username: username, + github_id, + }, + }); + + await targetClient.users.addToFederatedIdentity({ + realm: GOLD_GITHUB_REALM, + id: newuser.id, + federatedIdentityId: 'github', + federatedIdentity: { + userId: github_id, + userName: github_id, + identityProvider: 'github', + }, + }); + } catch {} + } + + if (count < max) break; + + first = first + max; + console.log(`complete ${first} users`); + } + + console.log(`${total} users imported.`); + process.exit(0); + } catch (err) { + handleError(err); + process.exit(1); + } +} + +main(); From 185945fae98355f079a87f87d76463eacc7a3867 Mon Sep 17 00:00:00 2001 From: Jonathan Sharman Date: Tue, 25 Oct 2022 11:28:24 -0700 Subject: [PATCH 006/118] chore: numofbackups --- .../values-6d70e7-dev-patroni-backup-storage.yaml | 7 +++++++ .../values-6d70e7-test-patroni-backup-storage.yaml | 7 +++++++ helm/backup-storage/values-eb75ad-prod-sso-backup.yaml | 2 +- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/helm/backup-storage/values-6d70e7-dev-patroni-backup-storage.yaml b/helm/backup-storage/values-6d70e7-dev-patroni-backup-storage.yaml index 8495a2cd..74fc339e 100644 --- a/helm/backup-storage/values-6d70e7-dev-patroni-backup-storage.yaml +++ b/helm/backup-storage/values-6d70e7-dev-patroni-backup-storage.yaml @@ -31,3 +31,10 @@ env: TABLE_SCHEMA: value: "public" + + DAILY_BACKUPS: + value: "7" + WEEKLY_BACKUPS: + value: "4" + MONTHLY_BACKUPS: + value: "1" diff --git a/helm/backup-storage/values-6d70e7-test-patroni-backup-storage.yaml b/helm/backup-storage/values-6d70e7-test-patroni-backup-storage.yaml index 7c894c26..37cb8f18 100644 --- a/helm/backup-storage/values-6d70e7-test-patroni-backup-storage.yaml +++ b/helm/backup-storage/values-6d70e7-test-patroni-backup-storage.yaml @@ -31,3 +31,10 @@ env: TABLE_SCHEMA: value: "public" + + DAILY_BACKUPS: + value: "7" + WEEKLY_BACKUPS: + value: "4" + MONTHLY_BACKUPS: + value: "1" diff --git a/helm/backup-storage/values-eb75ad-prod-sso-backup.yaml b/helm/backup-storage/values-eb75ad-prod-sso-backup.yaml index da5db328..435ca889 100644 --- a/helm/backup-storage/values-eb75ad-prod-sso-backup.yaml +++ b/helm/backup-storage/values-eb75ad-prod-sso-backup.yaml @@ -21,7 +21,7 @@ env: ENVIRONMENT_NAME: value: eb75ad-prod WEBHOOK_URL: - value: <> + value: "<>" secure: true DAILY_BACKUPS: From 7d982f4f340882abae8a62336c53038297b57071 Mon Sep 17 00:00:00 2001 From: Junmin Ahn Date: Tue, 25 Oct 2022 11:36:58 -0700 Subject: [PATCH 007/118] feat: add a keycloak script to delete dangling idp users --- scripts/keycloak-delete-dangling-idp-users.js | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 scripts/keycloak-delete-dangling-idp-users.js diff --git a/scripts/keycloak-delete-dangling-idp-users.js b/scripts/keycloak-delete-dangling-idp-users.js new file mode 100644 index 00000000..41d1688a --- /dev/null +++ b/scripts/keycloak-delete-dangling-idp-users.js @@ -0,0 +1,70 @@ +const _ = require('lodash'); +const { argv } = require('yargs'); +const Confirm = require('prompt-confirm'); +const { getAdminClient } = require('./keycloak-core'); +const { handleError, ignoreError } = require('./helpers'); +const { env, idp, realm, auto } = argv; + +async function main() { + if (!env || !idp || !realm) { + console.info(` + Usages: + node keycloak-delete-dangling-idp-users --env --idp --realm [--auto] + `); + + return; + } + + try { + const adminClient = await getAdminClient(env); + if (!adminClient) return; + + if (!auto) { + const prompt = new Confirm(`Are you sure to proceed in realm ${realm} of ${env} environment?`); + const answer = await prompt.run(); + if (!answer) return; + } + + const max = 500; + let first = 0; + + let searched = 0; + let deleted = 0; + + const idpSuffix = `@${idp}`; + + while (true) { + let users = await adminClient.users.find({ realm, username: idpSuffix, first, max }); + users = users.filter(({ username }) => username.endsWith(idpSuffix)); + const count = users.length; + if (count === 0) break; + + for (let x = 0; x < users.length; x++) { + const { id, username } = users[x]; + + const links = await adminClient.users.listFederatedIdentities({ realm, id }); + if (links.length === 0) { + await adminClient.users.del({ realm, id }); + console.log(`username ${username} deleted.`); + deleted++; + } + + searched++; + } + + if (count < max) break; + + first = first + max; + console.log(`complete ${first} users`); + } + + console.log(`${searched} users searched.`); + console.log(`${deleted} users deleted.`); + process.exit(0); + } catch (err) { + handleError(err); + process.exit(1); + } +} + +main(); From 475e61ab771c1bdb1f27902d106c04f499e164ad Mon Sep 17 00:00:00 2001 From: Junmin Ahn Date: Tue, 25 Oct 2022 11:58:02 -0700 Subject: [PATCH 008/118] chore: update dangling idp user deletion script --- scripts/keycloak-delete-dangling-idp-users.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/keycloak-delete-dangling-idp-users.js b/scripts/keycloak-delete-dangling-idp-users.js index 41d1688a..9b24219a 100644 --- a/scripts/keycloak-delete-dangling-idp-users.js +++ b/scripts/keycloak-delete-dangling-idp-users.js @@ -35,17 +35,18 @@ async function main() { while (true) { let users = await adminClient.users.find({ realm, username: idpSuffix, first, max }); - users = users.filter(({ username }) => username.endsWith(idpSuffix)); const count = users.length; if (count === 0) break; + users = users.filter(({ username }) => username.endsWith(idpSuffix)); + for (let x = 0; x < users.length; x++) { const { id, username } = users[x]; const links = await adminClient.users.listFederatedIdentities({ realm, id }); if (links.length === 0) { await adminClient.users.del({ realm, id }); - console.log(`username ${username} deleted.`); + console.log(`user ${username} deleted.`); deleted++; } From 72132aeac8656a51f9dfdcd7f7dd6568e70c74c4 Mon Sep 17 00:00:00 2001 From: Nithin Shekar Kuruba <81444731+NithinKuruba@users.noreply.github.com> Date: Wed, 26 Oct 2022 07:34:36 -0700 Subject: [PATCH 009/118] Using Cypress for Siteminder Tests (#210) * chore: adding cypress automation project for siteminder tests * chore: disable rc notif for testing * chore: updated dockerfile * chore: updated dockerfile * chore: re-enabled rocketchat notifications * chore: removed puppeteer project * chore: added readme --- .github/workflows/siteminder-tests.yml | 10 +- .gitignore | 1 + .../.env.example | 0 cy-siteminder-tests/.eslintrc.json | 23 + cy-siteminder-tests/.prettierrc | 5 + .../.tool-versions | 0 cy-siteminder-tests/Dockerfile | 19 + .../README.md | 47 +- cy-siteminder-tests/cypress.config.ts | 35 + .../cypress/app-config/config.ts | 50 + .../cypress/e2e/01.test.spec.ts | 93 + .../cypress/support/commands.ts | 119 ++ cy-siteminder-tests/cypress/support/e2e.ts | 21 + .../cypress/support/global.d.ts | 13 + cy-siteminder-tests/package.json | 30 + .../requirements.txt | 0 cy-siteminder-tests/tsconfig.json | 15 + .../yarn.lock | 1739 ++++++++--------- siteminder-tests/.dockerignore | 6 - siteminder-tests/.eslintrc.yml | 8 - siteminder-tests/.mocharc.js | 8 - siteminder-tests/.prettierignore | 1 - siteminder-tests/.prettierrc | 11 - siteminder-tests/Dockerfile | 17 - siteminder-tests/config.js | 55 - siteminder-tests/docker-compose.yml | 14 - siteminder-tests/package.json | 36 - siteminder-tests/tests/index.test.js | 85 - siteminder-tests/util.js | 89 - 29 files changed, 1197 insertions(+), 1353 deletions(-) rename {siteminder-tests => cy-siteminder-tests}/.env.example (100%) create mode 100644 cy-siteminder-tests/.eslintrc.json create mode 100644 cy-siteminder-tests/.prettierrc rename {siteminder-tests => cy-siteminder-tests}/.tool-versions (100%) create mode 100644 cy-siteminder-tests/Dockerfile rename {siteminder-tests => cy-siteminder-tests}/README.md (61%) create mode 100644 cy-siteminder-tests/cypress.config.ts create mode 100644 cy-siteminder-tests/cypress/app-config/config.ts create mode 100644 cy-siteminder-tests/cypress/e2e/01.test.spec.ts create mode 100644 cy-siteminder-tests/cypress/support/commands.ts create mode 100644 cy-siteminder-tests/cypress/support/e2e.ts create mode 100644 cy-siteminder-tests/cypress/support/global.d.ts create mode 100644 cy-siteminder-tests/package.json rename {siteminder-tests => cy-siteminder-tests}/requirements.txt (100%) create mode 100644 cy-siteminder-tests/tsconfig.json rename {siteminder-tests => cy-siteminder-tests}/yarn.lock (59%) delete mode 100644 siteminder-tests/.dockerignore delete mode 100644 siteminder-tests/.eslintrc.yml delete mode 100644 siteminder-tests/.mocharc.js delete mode 100644 siteminder-tests/.prettierignore delete mode 100644 siteminder-tests/.prettierrc delete mode 100644 siteminder-tests/Dockerfile delete mode 100755 siteminder-tests/config.js delete mode 100644 siteminder-tests/docker-compose.yml delete mode 100644 siteminder-tests/package.json delete mode 100644 siteminder-tests/tests/index.test.js delete mode 100644 siteminder-tests/util.js diff --git a/.github/workflows/siteminder-tests.yml b/.github/workflows/siteminder-tests.yml index 8946a535..8621df74 100644 --- a/.github/workflows/siteminder-tests.yml +++ b/.github/workflows/siteminder-tests.yml @@ -45,7 +45,7 @@ jobs: node-version: 16 - name: Generate env file run: | - cd ${{ github.workspace }}/siteminder-tests + cd ${{ github.workspace }}/cy-siteminder-tests echo "${{ secrets.SITEMINDER_TESTS_ENV }}" | base64 --decode > .env - name: Set up docker buildx uses: docker/setup-buildx-action@v2 @@ -58,7 +58,7 @@ jobs: - name: Build docker image uses: docker/build-push-action@v3 with: - context: siteminder-tests/ + context: cy-siteminder-tests/ push: false load: true tags: siteminder-tests @@ -70,10 +70,10 @@ jobs: mv /tmp/.buildx-test-cache-new /tmp/.buildx-test-cache - name: Run siteminder tests run: | - cd ${{ github.workspace }}/siteminder-tests + cd ${{ github.workspace }}/cy-siteminder-tests docker run --rm -e ENVIRONMENT=${{ github.event.inputs.environment }} \ -e CLUSTER=${{ github.event.inputs.cluster }} \ - -v $(pwd)/results:/app/results \ + -v $(pwd)/results:/e2e/results \ --add-host=${{ needs.matrix-prep.outputs.hostname }}:${{ matrix.ip }} \ siteminder-tests - name: Upload test results @@ -81,7 +81,7 @@ jobs: uses: actions/upload-artifact@v2 with: name: ${{ github.event.inputs.cluster }}-${{ github.event.inputs.environment }}-${{ matrix.name }}-results - path: ${{ github.workspace }}/siteminder-tests/results + path: ${{ github.workspace }}/cy-siteminder-tests/results - name: Rocket.Chat Notification if: failure() uses: fjogeleit/http-request-action@master diff --git a/.gitignore b/.gitignore index 48a0f7f1..bd8a424f 100644 --- a/.gitignore +++ b/.gitignore @@ -50,3 +50,4 @@ docker/keycloak/extensions/services/target screen_shots saml_trace results +screenshots diff --git a/siteminder-tests/.env.example b/cy-siteminder-tests/.env.example similarity index 100% rename from siteminder-tests/.env.example rename to cy-siteminder-tests/.env.example diff --git a/cy-siteminder-tests/.eslintrc.json b/cy-siteminder-tests/.eslintrc.json new file mode 100644 index 00000000..db2713d4 --- /dev/null +++ b/cy-siteminder-tests/.eslintrc.json @@ -0,0 +1,23 @@ +{ + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": 12, + "sourceType": "module" + }, + "plugins": ["cypress", "chai-friendly"], + "extends": ["plugin:cypress/recommended"], + + "rules": { + "cypress/no-assigning-return-values": "error", + "cypress/no-unnecessary-waiting": "error", + "cypress/assertion-before-screenshot": "warn", + "cypress/no-force": "warn", + "cypress/no-async-tests": "error", + "cypress/no-pause": "error", + "no-unused-expressions": 0, + "chai-friendly/no-unused-expressions": 2 + }, + "env": { + "cypress/globals": true + } +} diff --git a/cy-siteminder-tests/.prettierrc b/cy-siteminder-tests/.prettierrc new file mode 100644 index 00000000..09ceb594 --- /dev/null +++ b/cy-siteminder-tests/.prettierrc @@ -0,0 +1,5 @@ +{ + "semi": false, + "singleQuote": true, + "printWidth": 90 +} diff --git a/siteminder-tests/.tool-versions b/cy-siteminder-tests/.tool-versions similarity index 100% rename from siteminder-tests/.tool-versions rename to cy-siteminder-tests/.tool-versions diff --git a/cy-siteminder-tests/Dockerfile b/cy-siteminder-tests/Dockerfile new file mode 100644 index 00000000..a04ca865 --- /dev/null +++ b/cy-siteminder-tests/Dockerfile @@ -0,0 +1,19 @@ +FROM cypress/base:16.18.0 + +WORKDIR /e2e + +COPY *.json /e2e/ + +ENV CI=1 + +RUN npm install + +COPY cypress.config.ts /e2e/ + +COPY .env /e2e/ + +ADD cypress /e2e/cypress + +ENTRYPOINT ["npm", "run"] + +CMD ["cy:run"] diff --git a/siteminder-tests/README.md b/cy-siteminder-tests/README.md similarity index 61% rename from siteminder-tests/README.md rename to cy-siteminder-tests/README.md index 0211672d..ad2f2be8 100644 --- a/siteminder-tests/README.md +++ b/cy-siteminder-tests/README.md @@ -31,17 +31,10 @@ asdf reshim ``` -- `puppeteer`: To run it in linux, the following dependencies need to be installed - ```sh sudo apt-get update - sudo apt-get install gconf-service libasound2 libatk1.0-0 libatk-bridge2.0-0 libc6 libcairo2 \ - libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 \ - libglib2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 \ - libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 \ - libxrandr2 libxrender1 libxss1 libxtst6 ca-certificates fonts-liberation \ - libappindicator1 libnss3 lsb-release xdg-utils wget + sudo apt-get install libgtk2.0-0 libgtk-3-0 libgbm-dev libnotify-dev libgconf-2-4 libnss3 libxss1 libasound2 libxtst6 xauth xvfb ``` **Note**: Below steps is only for developers and contributors @@ -72,25 +65,13 @@ Install the dependencies -#### `yarn test` - -Executes all the tests and generates screenshots under `results/assets` - -#### `yarn test:html` +#### `yarn cy:run` -Executes all the tests and generates screenshots and html report under `results` directory +Executes all the tests and generates screenshots under `screenshots` folder upon errors. The test suite generates HTML report under `results` folder -**Note**: To run the tests on browser visually, update `beforeEach` hook in `./tests/index.test.js` file as shown below +#### `yarn cy:open` -```js - beforeEach(async function () { - browser = await puppeteer.launch({ - headless: false, - }); - page = await browser.newPage(); - await page.setViewport({ width: 800, height: 600 }); - }); -``` +Opens the Cypress application, where tests can be run visually ### Docker @@ -98,25 +79,11 @@ Executes all the tests and generates screenshots and html report under `results` - from `.env.example` and fill all the values or - from a secret [`siteminder-tests`](https://console.apps.gold.devops.gov.bc.ca/k8s/ns/eb75ad-tools/secrets/siteminder-tests/) -- Run the docker container from `siteminder-tests` directory +- Run the docker container from `cy-siteminder-tests` directory ```sh export ENVIRONMENT= export CLUSTER= - docker run --rm -e ENVIRONMENT=$ENVIRONMENT -e CLUSTER=$CLUSTER -v $(pwd)/results:/app/results $(docker build -q .) + docker run --rm -e ENVIRONMENT=$ENVIRONMENT -e CLUSTER=$CLUSTER -v $(pwd)/results:/e2e/results $(docker build -q .) ``` - -### Docker Compose - -- Create `.env` - - from `.env.example` and fill all the values or - - from a secret [`siteminder-tests`](https://console.apps.gold.devops.gov.bc.ca/k8s/ns/eb75ad-tools/secrets/siteminder-tests/) - -#### `docker-compose up` - -- Run the docker compose and optionally add flag `-d` to run it in the background - -### `docker-compose down` - -- Stop and remove the containers diff --git a/cy-siteminder-tests/cypress.config.ts b/cy-siteminder-tests/cypress.config.ts new file mode 100644 index 00000000..b1009f0c --- /dev/null +++ b/cy-siteminder-tests/cypress.config.ts @@ -0,0 +1,35 @@ +import * as dotenv from 'dotenv' +import { defineConfig } from 'cypress' + +dotenv.config({ path: __dirname + '/.env' }) + +export default defineConfig({ + reporter: 'cypress-mochawesome-reporter', + reporterOptions: { + saveJson: true, + charts: true, + embeddedScreenshots: true, + inlineAssets: true, + saveAllAttempts: false, + reportDir: 'results', + reportTitle: 'SSO Siteminder Tests', + overwrite: false, + }, + e2e: { + screenshotOnRunFailure: true, + defaultCommandTimeout: 10000, + requestTimeout: 10000, + retries: 1, + specPattern: 'cypress/e2e/**.spec.ts', + setupNodeEvents(on, config) { + require('cypress-mochawesome-reporter/plugin')(on) + config.env = { + ...process.env, + ...config.env, + } + return config + }, + video: false, + videoUploadOnPasses: false, + }, +}) diff --git a/cy-siteminder-tests/cypress/app-config/config.ts b/cy-siteminder-tests/cypress/app-config/config.ts new file mode 100644 index 00000000..678abab1 --- /dev/null +++ b/cy-siteminder-tests/cypress/app-config/config.ts @@ -0,0 +1,50 @@ +const environment = Cypress.env('ENVIRONMENT').toUpperCase() || 'DEV' + +const cluster = Cypress.env('CLUSTER').toUpperCase() || 'SILVER' + +const fetchEnvParam = (param: string) => { + // Silver dev uses same credentials as test + if (cluster === 'SILVER' && environment === 'DEV') return Cypress.env(`TEST_${param}`) + return Cypress.env(`${environment}_${param}`) +} + +export const fetchSsoUrl = (provider: string) => { + let realm = Cypress.env(`${cluster}_${provider}_REALM`) + if (cluster === 'SILVER') { + return `https://${ + Cypress.env('ENVIRONMENT') === 'prod' ? '' : Cypress.env('ENVIRONMENT') + '.' + }oidc.gov.bc.ca/auth/admin/${realm}/console/` + } else { + return `https://${ + Cypress.env('ENVIRONMENT') === 'prod' ? '' : Cypress.env('ENVIRONMENT') + '.' + }loginproxy.gov.bc.ca/auth/admin/${realm}/console/` + } +} + +export const idir_config = { + username: Cypress.env('IDIR_USERNAME'), + password: Cypress.env('IDIR_PASSWORD'), + user_identifier: Cypress.env('IDIR_USER_IDENTIFIER'), + display_name: Cypress.env('IDIR_DISPLAYNAME'), + email: Cypress.env('IDIR_EMAIL'), + firstname: Cypress.env('IDIR_FIRSTNAME'), + lastname: Cypress.env('IDIR_LASTNAME'), +} + +export const bceid_basic_config = { + username: fetchEnvParam('BCEID_BASIC_USERNAME'), + password: fetchEnvParam('BCEID_BASIC_PASSWORD'), + user_identifier: fetchEnvParam('BCEID_BASIC_USER_IDENTIFIER'), + display_name: fetchEnvParam('BCEID_BASIC_DISPLAYNAME'), + email: fetchEnvParam('BCEID_BASIC_EMAIL'), +} + +export const bceid_business_config = { + username: fetchEnvParam('BCEID_BUSINESS_USERNAME'), + password: fetchEnvParam('BCEID_BUSINESS_PASSWORD'), + user_identifier: fetchEnvParam('BCEID_BUSINESS_USER_IDENTIFIER'), + display_name: fetchEnvParam('BCEID_BUSINESS_DISPLAYNAME'), + email: fetchEnvParam('BCEID_BUSINESS_EMAIL'), + guid: fetchEnvParam('BCEID_BUSINESS_GUID'), + legalname: fetchEnvParam('BCEID_BUSINESS_LEGALNAME'), +} diff --git a/cy-siteminder-tests/cypress/e2e/01.test.spec.ts b/cy-siteminder-tests/cypress/e2e/01.test.spec.ts new file mode 100644 index 00000000..8895ee0c --- /dev/null +++ b/cy-siteminder-tests/cypress/e2e/01.test.spec.ts @@ -0,0 +1,93 @@ +import { + bceid_basic_config, + bceid_business_config, + fetchSsoUrl, + idir_config, +} from '../app-config/config' + +describe('siteminder tests', () => { + it('IDIR', () => { + cy.testsite(fetchSsoUrl('IDIR'), idir_config.username, idir_config.password, 'IDIR') + cy.get('@samlattributes').then((data: any) => { + assert.deepEqual(data.guid, idir_config.user_identifier, 'user_identifier') + assert.deepEqual(data.display_name, idir_config.display_name, 'display_name') + assert.deepEqual(data.username, idir_config.username, 'username') + assert.deepEqual(data.email, idir_config.email, 'email') + assert.deepEqual(data.firstname, idir_config.firstname, 'firstname') + assert.deepEqual(data.lastname, idir_config.lastname, 'lastname') + }) + }) + + it('Basic BCeID', () => { + cy.testsite( + fetchSsoUrl('BCEID_BASIC'), + bceid_basic_config.username, + bceid_basic_config.password, + 'BCEID_BASIC' + ) + cy.get('@samlattributes').then((data: any) => { + assert.deepEqual(data.guid, bceid_basic_config.user_identifier, 'user_identifier') + assert.deepEqual(data.display_name, bceid_basic_config.display_name, 'display_name') + assert.deepEqual(data.username, bceid_basic_config.username, 'username') + assert.deepEqual(data.email, bceid_basic_config.email, 'email') + }) + }) + + it('Business BCeID', () => { + cy.testsite( + fetchSsoUrl('BCEID_BUSINESS'), + bceid_business_config.username, + bceid_business_config.password, + 'BCEID_BUSINESS' + ) + cy.get('@samlattributes').then((data: any) => { + assert.deepEqual( + data.guid, + bceid_business_config.user_identifier, + 'user_identifier' + ) + assert.deepEqual( + data.display_name, + bceid_business_config.display_name, + 'display_name' + ) + assert.deepEqual(data.username, bceid_business_config.username, 'username') + assert.deepEqual(data.email, bceid_business_config.email, 'email') + assert.deepEqual(data.business_guid, bceid_business_config.guid, 'business guid') + assert.deepEqual( + data.business_legalname, + bceid_business_config.legalname, + 'business legalname' + ) + }) + }) + + it('Basic/Business BCeID', () => { + cy.testsite( + fetchSsoUrl('BCEID_BOTH'), + bceid_business_config.username, + bceid_business_config.password, + 'BCEID_BASIC_BUSINESS' + ) + cy.get('@samlattributes').then((data: any) => { + assert.deepEqual( + data.guid, + bceid_business_config.user_identifier, + 'user_identifier' + ) + assert.deepEqual( + data.display_name, + bceid_business_config.display_name, + 'display_name' + ) + assert.deepEqual(data.username, bceid_business_config.username, 'username') + assert.deepEqual(data.email, bceid_business_config.email, 'email') + assert.equal(data.business_guid, bceid_business_config.guid, 'business guid') + assert.deepEqual( + data.business_legalname, + bceid_business_config.legalname, + 'business legalname' + ) + }) + }) +}) diff --git a/cy-siteminder-tests/cypress/support/commands.ts b/cy-siteminder-tests/cypress/support/commands.ts new file mode 100644 index 00000000..d841f32a --- /dev/null +++ b/cy-siteminder-tests/cypress/support/commands.ts @@ -0,0 +1,119 @@ +/// + +import { Interception } from 'cypress/types/net-stubbing' +import { promisify } from 'util' +const parseString = require('xml2js').parseString +const parseStringSync = promisify(parseString) +const Buffer = require('buffer').Buffer +const _ = require('lodash') + +// *********************************************** +// This example commands.ts shows you how to +// create various custom commands and overwrite +// existing commands. +// +// For more comprehensive examples of custom +// commands please read more here: +// https://on.cypress.io/custom-commands +// *********************************************** +// +// +// -- This is a parent command -- +// Cypress.Commands.add('login', (email, password) => { ... }) +// +// +// -- This is a child command -- +// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... }) +// +// +// -- This is a dual command -- +// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... }) +// +// +// -- This will overwrite an existing command -- +// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) +// +// declare global { +// namespace Cypress { +// interface Chainable { +// login(email: string, password: string): Chainable +// drag(subject: string, options?: Partial): Chainable +// dismiss(subject: string, options?: Partial): Chainable +// visit(originalFn: CommandOriginalFn, url: string, options: Partial): Chainable +// } +// } +// } + +Cypress.Commands.add('login', (url: string, username: string, password: string) => { + cy.visit(url) + cy.get('[id=user]').click().type(username) + cy.get('[id=password]').click().type(password) + cy.get('[name=btnSubmit]').click() +}) +Cypress.Commands.add( + 'testsite', + (url: string, username: string, password: string, idp: string) => { + cy.login(url, username, password) + if (idp !== 'IDIR') { + cy.get('input[value=Continue]').click() + } + + cy.intercept('POST', '**/endpoint').as('samlresponse') + cy.wait('@samlresponse').then(async (interception: Interception) => { + const entries = parseFormData(interception.request.body) + const cleanSamlResponse = entries.SAMLResponse.replace(/(\r\n|\n|\r)/gm, '') + const decodedXML = decodeBase64(cleanSamlResponse) + const jsonResult = await parseStringSync(decodedXML) + const assertion = _.get(jsonResult, 'Response.ns2:Assertion.0') + + const getAttribute = (data: any) => ({ + [_.get(data, '$.Name')]: _.get(data, 'ns2:AttributeValue.0'), + }) + const statements = _.get(assertion, 'ns2:AttributeStatement.0.ns2:Attribute') + + const attributes = _.reduce( + statements, + (ret: any, data: any) => ({ ...ret, ...getAttribute(data) }), + {} + ) + cy.wrap(updateSiteminderVals(attributes)).as('samlattributes') + }) + } +) + +const parseFormData = (data: any) => { + const vars = data.split('&') + const map = Object.create(null) + for (let i = 0; i < vars.length; i++) { + let pair = vars[i].split('=') + if (pair.length === 2) { + pair = pair.map(decodeURIComponent) + map[pair[0]] = pair[1] + } + } + + return map +} + +const decodeBase64 = (data: any) => { + let buff = Buffer.from(data, 'base64') + return buff.toString('ascii') +} + +const updateSiteminderVals = (attributes: any) => { + const result: any = {} + + result.guid = attributes['useridentifier'] ?? attributes['SMGOV_USERGUID'] ?? '' + result.username = attributes['username'] + result.email = attributes['email'] + result.display_name = + attributes['displayname'] ?? + attributes['displayName'] ?? + attributes['SMGOV_USERDISPLAYNAME'] ?? + '' + result.firstname = attributes['firstname'] ?? '' + result.lastname = attributes['lastname'] ?? '' + result.business_guid = attributes['SMGOV_BUSINESSGUID'] ?? '' + result.business_legalname = attributes['SMGOV_BUSINESSLEGALNAME'] ?? '' + return result +} diff --git a/cy-siteminder-tests/cypress/support/e2e.ts b/cy-siteminder-tests/cypress/support/e2e.ts new file mode 100644 index 00000000..b856eebe --- /dev/null +++ b/cy-siteminder-tests/cypress/support/e2e.ts @@ -0,0 +1,21 @@ +// *********************************************************** +// This example support/e2e.ts is processed and +// loaded automatically before your test files. +// +// This is a great place to put global configuration and +// behavior that modifies Cypress. +// +// You can change the location of this file or turn off +// automatically serving support files with the +// 'supportFile' configuration option. +// +// You can read more here: +// https://on.cypress.io/configuration +// *********************************************************** + +// Import commands.js using ES2015 syntax: +import './commands' +import 'cypress-mochawesome-reporter/register' + +// Alternatively you can use CommonJS syntax: +// require('./commands') diff --git a/cy-siteminder-tests/cypress/support/global.d.ts b/cy-siteminder-tests/cypress/support/global.d.ts new file mode 100644 index 00000000..783a920d --- /dev/null +++ b/cy-siteminder-tests/cypress/support/global.d.ts @@ -0,0 +1,13 @@ +/// + +declare namespace Cypress { + interface Chainable { + login(url: string, username: string, password: string): Chainable + testsite( + url: string, + username: string, + password: string, + idp: string + ): Chainable + } +} diff --git a/cy-siteminder-tests/package.json b/cy-siteminder-tests/package.json new file mode 100644 index 00000000..10d4fac3 --- /dev/null +++ b/cy-siteminder-tests/package.json @@ -0,0 +1,30 @@ +{ + "name": "cypress-siteminder-tests", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "cy:open": "cypress open", + "cy:run": "cypress run" + }, + "keywords": [], + "author": "", + "license": "ISC", + "devDependencies": { + "@types/mocha": "^10.0.0", + "@types/mochawesome": "^6.2.1", + "@types/node": "^18.11.5", + "cypress": "^10.10.0", + "cypress-mochawesome-reporter": "^3.2.2", + "eslint": "^8.26.0", + "eslint-plugin-cypress": "^2.12.1", + "mocha": "^10.1.0", + "prettier": "^2.7.1", + "typescript": "^4.8.4" + }, + "dependencies": { + "dotenv": "^16.0.3", + "lodash": "^4.17.21", + "xml2js": "^0.4.23" + } +} diff --git a/siteminder-tests/requirements.txt b/cy-siteminder-tests/requirements.txt similarity index 100% rename from siteminder-tests/requirements.txt rename to cy-siteminder-tests/requirements.txt diff --git a/cy-siteminder-tests/tsconfig.json b/cy-siteminder-tests/tsconfig.json new file mode 100644 index 00000000..5657c2d2 --- /dev/null +++ b/cy-siteminder-tests/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "target": "es6", + "lib": ["es5", "dom", "ES2015", "ES6", "ESNext"], + "types": ["cypress", "node"], + "allowJs": true, + "noImplicitAny": true, + "strict": true, + "module": "commonjs", + "baseUrl": "." + }, + "include": ["./cypress/", "**/*.d.ts", "cypress.config.ts"], + "exclude": ["./node_modules"], + "noEmit": true +} diff --git a/siteminder-tests/yarn.lock b/cy-siteminder-tests/yarn.lock similarity index 59% rename from siteminder-tests/yarn.lock rename to cy-siteminder-tests/yarn.lock index 58f2c05f..731a123e 100644 --- a/siteminder-tests/yarn.lock +++ b/cy-siteminder-tests/yarn.lock @@ -2,14 +2,51 @@ # yarn lockfile v1 -"@eslint/eslintrc@^1.3.0": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.0.tgz#29f92c30bb3e771e4a2048c95fa6855392dfac4f" - integrity sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw== +"@colors/colors@1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" + integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== + +"@cypress/request@^2.88.10": + version "2.88.10" + resolved "https://registry.yarnpkg.com/@cypress/request/-/request-2.88.10.tgz#b66d76b07f860d3a4b8d7a0604d020c662752cce" + integrity sha512-Zp7F+R93N0yZyG34GutyTNr+okam7s/Fzc1+i3kcqOP8vk6OuajuE9qZJ6Rs+10/1JFtXFYMdyarnU1rZuJesg== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + http-signature "~1.3.6" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.5.0" + tunnel-agent "^0.6.0" + uuid "^8.3.2" + +"@cypress/xvfb@^1.2.4": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@cypress/xvfb/-/xvfb-1.2.4.tgz#2daf42e8275b39f4aa53c14214e557bd14e7748a" + integrity sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q== + dependencies: + debug "^3.1.0" + lodash.once "^4.1.1" + +"@eslint/eslintrc@^1.3.3": + version "1.3.3" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.3.tgz#2b044ab39fdfa75b4688184f9e573ce3c5b0ff95" + integrity sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg== dependencies: ajv "^6.12.4" debug "^4.3.2" - espree "^9.3.2" + espree "^9.4.0" globals "^13.15.0" ignore "^5.2.0" import-fresh "^3.2.1" @@ -17,24 +54,77 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@humanwhocodes/config-array@^0.9.2": - version "0.9.5" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.9.5.tgz#2cbaf9a89460da24b5ca6531b8bbfc23e1df50c7" - integrity sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw== +"@humanwhocodes/config-array@^0.11.6": + version "0.11.6" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.6.tgz#6a51d603a3aaf8d4cf45b42b3f2ac9318a4adc4b" + integrity sha512-jJr+hPTJYKyDILJfhNSHsjiwXYf26Flsz8DvNndOsHs5pwSnpGUEy8yzF0JYhCEvTDdV2vuOK5tt8BVhwO5/hg== dependencies: "@humanwhocodes/object-schema" "^1.2.1" debug "^4.1.1" minimatch "^3.0.4" +"@humanwhocodes/module-importer@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" + integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== + "@humanwhocodes/object-schema@^1.2.1": version "1.2.1" resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== -"@types/node@*": - version "18.0.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.0.6.tgz#0ba49ac517ad69abe7a1508bc9b3a5483df9d5d7" - integrity sha512-/xUq6H2aQm261exT6iZTMifUySEt4GR5KX8eYyY+C4MSNPqSh9oNIP7tz2GLKTlFaiBbgZNxffoR3CVRG+cljw== +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.8": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@types/mocha@*", "@types/mocha@^10.0.0": + version "10.0.0" + resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-10.0.0.tgz#3d9018c575f0e3f7386c1de80ee66cc21fbb7a52" + integrity sha512-rADY+HtTOA52l9VZWtgQfn4p+UDVM2eDVkMZT1I6syp0YKxW2F9v+0pbRZLsvskhQv/vMb6ZfCay81GHbz5SHg== + +"@types/mochawesome@^6.2.1": + version "6.2.1" + resolved "https://registry.yarnpkg.com/@types/mochawesome/-/mochawesome-6.2.1.tgz#4d81b570a44812c216a592b1785d9829c2e96425" + integrity sha512-AhQdBkT/CBdx3sI9ATeljqa5uJ3dGNKEJnsgzw9IkPeg9d9Lzxsz1eKFnenxq1qQojIW0XkIsCgdheRRXP2SQA== + dependencies: + "@types/mocha" "*" + +"@types/node@*", "@types/node@^18.11.5": + version "18.11.5" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.5.tgz#1bc94cf2f9ab5fe33353bc7c79c797dcc5325bef" + integrity sha512-3JRwhbjI+cHLAkUorhf8RnqUbFXajvzX4q6fMn5JwkgtuwfYtRQYI3u4V92vI6NJuTsbBQWWh3RZjFsuevyMGQ== + +"@types/node@^14.14.31": + version "14.18.32" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.32.tgz#8074f7106731f1a12ba993fe8bad86ee73905014" + integrity sha512-Y6S38pFr04yb13qqHf8uk1nHE3lXgQ30WZbv1mLliV9pt0NjvqdWttLcrOYLnXbOafknVYRHZGoMSpR9UwfYow== + +"@types/sinonjs__fake-timers@8.1.1": + version "8.1.1" + resolved "https://registry.yarnpkg.com/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz#b49c2c70150141a15e0fa7e79cf1f92a72934ce3" + integrity sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g== + +"@types/sizzle@^2.3.2": + version "2.3.3" + resolved "https://registry.yarnpkg.com/@types/sizzle/-/sizzle-2.3.3.tgz#ff5e2f1902969d305225a047c8a0fd5c915cebef" + integrity sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ== "@types/yauzl@^2.9.1": version "2.10.0" @@ -43,29 +133,25 @@ dependencies: "@types/node" "*" -"@ungap/promise-all-settled@1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" - integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== - acorn-jsx@^5.3.2: version "5.3.2" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== -acorn@^8.7.1: - version "8.7.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.1.tgz#0197122c843d1bf6d0a5e83220a788f278f63c30" - integrity sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A== +acorn@^8.8.0: + version "8.8.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.1.tgz#0a3f9cbecc4ec3bea6f0a80b66ae8dd2da250b73" + integrity sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA== -agent-base@6: - version "6.0.2" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" - integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== +aggregate-error@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" + integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== dependencies: - debug "4" + clean-stack "^2.0.0" + indent-string "^4.0.0" -ajv@^6.10.0, ajv@^6.12.3, ajv@^6.12.4: +ajv@^6.10.0, ajv@^6.12.4: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -80,18 +166,23 @@ ansi-colors@4.1.1: resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== +ansi-colors@^4.1.1: + version "4.1.3" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" + integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== + +ansi-escapes@^4.3.0: + version "4.3.2" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== + dependencies: + type-fest "^0.21.3" + ansi-regex@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== -ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - ansi-styles@^4.0.0, ansi-styles@^4.1.0: version "4.3.0" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" @@ -107,6 +198,11 @@ anymatch@~3.1.2: normalize-path "^3.0.0" picomatch "^2.0.4" +arch@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/arch/-/arch-2.2.0.tgz#1bc47818f305764f23ab3306b0bfc086c5a29d11" + integrity sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ== + argparse@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" @@ -124,12 +220,12 @@ assert-plus@1.0.0, assert-plus@^1.0.0: resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw== -assertion-error@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" - integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== +astral-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" + integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== -async@^3.2.4: +async@^3.2.0: version "3.2.4" resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c" integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ== @@ -139,6 +235,11 @@ asynckit@^0.4.0: resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== +at-least-node@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" + integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== + aws-sign2@~0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" @@ -171,21 +272,15 @@ binary-extensions@^2.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== -bindings@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" - integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== - dependencies: - file-uri-to-path "1.0.0" +blob-util@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/blob-util/-/blob-util-2.0.2.tgz#3b4e3c281111bb7f11128518006cdc60b403a1eb" + integrity sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ== -bl@^4.0.3: - version "4.1.0" - resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" - integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== - dependencies: - buffer "^5.5.0" - inherits "^2.0.4" - readable-stream "^3.4.0" +bluebird@^3.7.2: + version "3.7.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== brace-expansion@^1.1.7: version "1.1.11" @@ -219,7 +314,7 @@ buffer-crc32@~0.2.3: resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ== -buffer@^5.2.1, buffer@^5.5.0: +buffer@^5.6.0: version "5.7.1" resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== @@ -227,19 +322,21 @@ buffer@^5.2.1, buffer@^5.5.0: base64-js "^1.3.1" ieee754 "^1.1.13" -call-bind@^1.0.0, call-bind@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== - dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" +cachedir@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/cachedir/-/cachedir-2.3.0.tgz#0c75892a052198f0b21c7c1804d8331edfcae0e8" + integrity sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw== callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== +camelcase@^5.0.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + camelcase@^6.0.0: version "6.3.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" @@ -250,28 +347,6 @@ caseless@~0.12.0: resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw== -chai@^4.3.6: - version "4.3.6" - resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.6.tgz#ffe4ba2d9fa9d6680cc0b370adae709ec9011e9c" - integrity sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q== - dependencies: - assertion-error "^1.1.0" - check-error "^1.0.2" - deep-eql "^3.0.1" - get-func-name "^2.0.0" - loupe "^2.3.1" - pathval "^1.1.1" - type-detect "^4.0.5" - -chalk@^2.4.1: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" @@ -280,10 +355,10 @@ chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: ansi-styles "^4.1.0" supports-color "^7.1.0" -check-error@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" - integrity sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA== +check-more-types@^2.24.0: + version "2.24.0" + resolved "https://registry.yarnpkg.com/check-more-types/-/check-more-types-2.24.0.tgz#1420ffb10fd444dcfc79b43891bbfffd32a84600" + integrity sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA== chokidar@3.5.3: version "3.5.3" @@ -300,10 +375,48 @@ chokidar@3.5.3: optionalDependencies: fsevents "~2.3.2" -chownr@^1.1.1: - version "1.1.4" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" - integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== +ci-info@^3.2.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.5.0.tgz#bfac2a29263de4c829d806b1ab478e35091e171f" + integrity sha512-yH4RezKOGlOhxkmhbeNuC4eYZKAUsEaGtBuBzDDP1eFUKiccDWzBABxBfOx31IDwDIXMTxWuwAxUGModvkbuVw== + +clean-stack@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" + integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== + +cli-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" + integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== + dependencies: + restore-cursor "^3.1.0" + +cli-table3@~0.6.1: + version "0.6.3" + resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.3.tgz#61ab765aac156b52f222954ffc607a6f01dbeeb2" + integrity sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg== + dependencies: + string-width "^4.2.0" + optionalDependencies: + "@colors/colors" "1.5.0" + +cli-truncate@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-2.1.0.tgz#c39e28bf05edcde5be3b98992a22deed5a2b93c7" + integrity sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg== + dependencies: + slice-ansi "^3.0.0" + string-width "^4.2.0" + +cliui@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1" + integrity sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^6.2.0" cliui@^7.0.2: version "7.0.4" @@ -314,12 +427,14 @@ cliui@^7.0.2: strip-ansi "^6.0.0" wrap-ansi "^7.0.0" -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== +cliui@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" + integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== dependencies: - color-name "1.1.3" + string-width "^4.2.0" + strip-ansi "^6.0.1" + wrap-ansi "^7.0.0" color-convert@^2.0.1: version "2.0.1" @@ -328,16 +443,16 @@ color-convert@^2.0.1: dependencies: color-name "~1.1.4" -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== - color-name@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +colorette@^2.0.16: + version "2.0.19" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798" + integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ== + combined-stream@^1.0.6, combined-stream@~1.0.6: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" @@ -345,6 +460,16 @@ combined-stream@^1.0.6, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" +commander@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae" + integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg== + +common-tags@^1.8.0: + version "1.8.2" + resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.2.tgz#94ebb3c076d26032745fd54face7f688ef5ac9c6" + integrity sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA== + concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" @@ -355,25 +480,7 @@ core-util-is@1.0.2: resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ== -cross-fetch@3.1.5: - version "3.1.5" - resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.5.tgz#e1389f44d9e7ba767907f7af8454787952ab534f" - integrity sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw== - dependencies: - node-fetch "2.6.7" - -cross-spawn@^6.0.5: - version "6.0.5" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" - integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== - dependencies: - nice-try "^1.0.4" - path-key "^2.0.1" - semver "^5.5.0" - shebang-command "^1.2.0" - which "^1.2.9" - -cross-spawn@^7.0.2: +cross-spawn@^7.0.0, cross-spawn@^7.0.2: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== @@ -382,6 +489,64 @@ cross-spawn@^7.0.2: shebang-command "^2.0.0" which "^2.0.1" +cypress-mochawesome-reporter@^3.2.2: + version "3.2.3" + resolved "https://registry.yarnpkg.com/cypress-mochawesome-reporter/-/cypress-mochawesome-reporter-3.2.3.tgz#01f19c626b651d964cf0e56e10ee72d8e251fe12" + integrity sha512-gUtIYBH+KvnAeCkTFu/t9niX1KHnAbEZyxBFvEHQRtrQNXLERjLJjGOHIW6kuESIdVMiEFOcvuNF2LuBpORW9A== + dependencies: + fs-extra "^10.0.1" + mochawesome "^7.1.3" + mochawesome-merge "^4.2.1" + mochawesome-report-generator "^6.2.0" + +cypress@^10.10.0: + version "10.10.0" + resolved "https://registry.yarnpkg.com/cypress/-/cypress-10.10.0.tgz#fd671297b2ca3e64dfffd55fe3857c388cfbb695" + integrity sha512-bU8r44x1NIYAUNNXt3CwJpLOVth7HUv2hUhYCxZmgZ1IugowDvuHNpevnoZRQx1KKOEisLvIJW+Xen5Pjn41pg== + dependencies: + "@cypress/request" "^2.88.10" + "@cypress/xvfb" "^1.2.4" + "@types/node" "^14.14.31" + "@types/sinonjs__fake-timers" "8.1.1" + "@types/sizzle" "^2.3.2" + arch "^2.2.0" + blob-util "^2.0.2" + bluebird "^3.7.2" + buffer "^5.6.0" + cachedir "^2.3.0" + chalk "^4.1.0" + check-more-types "^2.24.0" + cli-cursor "^3.1.0" + cli-table3 "~0.6.1" + commander "^5.1.0" + common-tags "^1.8.0" + dayjs "^1.10.4" + debug "^4.3.2" + enquirer "^2.3.6" + eventemitter2 "6.4.7" + execa "4.1.0" + executable "^4.1.1" + extract-zip "2.0.1" + figures "^3.2.0" + fs-extra "^9.1.0" + getos "^3.2.1" + is-ci "^3.0.0" + is-installed-globally "~0.4.0" + lazy-ass "^1.6.0" + listr2 "^3.8.3" + lodash "^4.17.21" + log-symbols "^4.0.0" + minimist "^1.2.6" + ospath "^1.2.2" + pretty-bytes "^5.6.0" + proxy-from-env "1.0.0" + request-progress "^3.0.0" + semver "^7.3.2" + supports-color "^8.1.1" + tmp "~0.2.1" + untildify "^4.0.0" + yauzl "^2.10.0" + dashdash@^1.12.0: version "1.14.1" resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" @@ -394,68 +559,45 @@ dateformat@^4.5.1: resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-4.6.3.tgz#556fa6497e5217fedb78821424f8a1c22fa3f4b5" integrity sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA== -deasync-promise@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/deasync-promise/-/deasync-promise-1.0.1.tgz#2b27de478167af4ef34ba99879c52ec0cedd61c2" - integrity sha512-VzJ6J6beJcSXM7SMVhug3JNZzLiPGUNJWDuevXcFeXQCa+zlnP7ZrByI+8DZQZ3AoZJj9W32ceqF6JBKmsTdgg== - dependencies: - deasync "^0.1.7" - -deasync@^0.1.7: - version "0.1.27" - resolved "https://registry.yarnpkg.com/deasync/-/deasync-0.1.27.tgz#2a669a68d2d43bf8effa5a7efe7d8e1f1e447216" - integrity sha512-aCt6M9Ilkvs8TKIchmibUpNe/QSp9UNQL6YkvVraAce/SFFZCvYw3lQevl6MlUDn8Xr4QD4wYTerWH22yn+ODQ== - dependencies: - bindings "^1.5.0" - node-addon-api "^1.7.1" +dayjs@^1.10.4: + version "1.11.6" + resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.6.tgz#2e79a226314ec3ec904e3ee1dd5a4f5e5b1c7afb" + integrity sha512-zZbY5giJAinCG+7AGaw0wIhNZ6J8AhWuSXKvuc1KAyMiRsvGQWqh4L+MomvhdAYjN+lqvVCMq1I41e3YHvXkyQ== -debug@4, debug@4.3.4, debug@^4.1.1, debug@^4.3.2: +debug@4.3.4, debug@^4.1.1, debug@^4.3.2: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== dependencies: ms "2.1.2" +debug@^3.1.0: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + +decamelize@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== + decamelize@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== -deep-eql@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" - integrity sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw== - dependencies: - type-detect "^4.0.0" - deep-is@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== -define-properties@^1.1.3, define-properties@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1" - integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA== - dependencies: - has-property-descriptors "^1.0.0" - object-keys "^1.1.1" - -delay@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/delay/-/delay-5.0.0.tgz#137045ef1b96e5071060dd5be60bf9334436bd1d" - integrity sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw== - delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== -devtools-protocol@0.0.1011705: - version "0.0.1011705" - resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.1011705.tgz#2582ed29f84848df83fba488122015540a744539" - integrity sha512-OKvTvu9n3swmgYshvsyVHYX0+aPzCoYUnyXUacfQMmFtBtBKewV/gT4I9jkAbpTqtTi2E4S9MXLlvzBDUlqg0Q== - diff@5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" @@ -473,10 +615,10 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" -dotenv@^16.0.1: - version "16.0.1" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.1.tgz#8f8f9d94876c35dac989876a5d3a82a267fdce1d" - integrity sha512-1K6hR6wtk2FviQ4kEiSjFiH5rpzEVi8WW0x96aztHVMhEspNpc4DVOUTEHtEva5VThQ8IaBX1Pe4gSzpVVUsKQ== +dotenv@^16.0.3: + version "16.0.3" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.3.tgz#115aec42bac5053db3c456db30cc243a5a836a07" + integrity sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ== ecc-jsbn@~0.1.1: version "0.1.2" @@ -491,57 +633,19 @@ emoji-regex@^8.0.0: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== -end-of-stream@^1.1.0, end-of-stream@^1.4.1: +end-of-stream@^1.1.0: version "1.4.4" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== dependencies: once "^1.4.0" -error-ex@^1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== - dependencies: - is-arrayish "^0.2.1" - -es-abstract@^1.19.0, es-abstract@^1.19.1, es-abstract@^1.19.5: - version "1.20.1" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.1.tgz#027292cd6ef44bd12b1913b828116f54787d1814" - integrity sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA== - dependencies: - call-bind "^1.0.2" - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - function.prototype.name "^1.1.5" - get-intrinsic "^1.1.1" - get-symbol-description "^1.0.0" - has "^1.0.3" - has-property-descriptors "^1.0.0" - has-symbols "^1.0.3" - internal-slot "^1.0.3" - is-callable "^1.2.4" - is-negative-zero "^2.0.2" - is-regex "^1.1.4" - is-shared-array-buffer "^1.0.2" - is-string "^1.0.7" - is-weakref "^1.0.2" - object-inspect "^1.12.0" - object-keys "^1.1.1" - object.assign "^4.1.2" - regexp.prototype.flags "^1.4.3" - string.prototype.trimend "^1.0.5" - string.prototype.trimstart "^1.0.5" - unbox-primitive "^1.0.2" - -es-to-primitive@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" - integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== +enquirer@^2.3.6: + version "2.3.6" + resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" + integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" + ansi-colors "^4.1.1" escalade@^3.1.1: version "3.1.1" @@ -563,6 +667,13 @@ escape-string-regexp@^1.0.5: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== +eslint-plugin-cypress@^2.12.1: + version "2.12.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-cypress/-/eslint-plugin-cypress-2.12.1.tgz#9aeee700708ca8c058e00cdafe215199918c2632" + integrity sha512-c2W/uPADl5kospNDihgiLc7n87t5XhUbFDoTl6CfVkmG+kDAb5Ux10V9PoLPu9N+r7znpc+iQlcmAqT1A/89HA== + dependencies: + globals "^11.12.0" + eslint-scope@^7.1.1: version "7.1.1" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.1.1.tgz#fff34894c2f65e5226d3041ac480b4513a163642" @@ -588,13 +699,15 @@ eslint-visitor-keys@^3.3.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== -eslint@^8.20.0: - version "8.20.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.20.0.tgz#048ac56aa18529967da8354a478be4ec0a2bc81b" - integrity sha512-d4ixhz5SKCa1D6SCPrivP7yYVi7nyD6A4vs6HIAul9ujBzcEmZVM3/0NN/yu5nKhmO1wjp5xQ46iRfmDGlOviA== +eslint@^8.26.0: + version "8.26.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.26.0.tgz#2bcc8836e6c424c4ac26a5674a70d44d84f2181d" + integrity sha512-kzJkpaw1Bfwheq4VXUezFriD1GxszX6dUekM7Z3aC2o4hju+tsR/XyTC3RcoSD7jmy9VkPU3+N6YjVU2e96Oyg== dependencies: - "@eslint/eslintrc" "^1.3.0" - "@humanwhocodes/config-array" "^0.9.2" + "@eslint/eslintrc" "^1.3.3" + "@humanwhocodes/config-array" "^0.11.6" + "@humanwhocodes/module-importer" "^1.0.1" + "@nodelib/fs.walk" "^1.2.8" ajv "^6.10.0" chalk "^4.0.0" cross-spawn "^7.0.2" @@ -604,18 +717,21 @@ eslint@^8.20.0: eslint-scope "^7.1.1" eslint-utils "^3.0.0" eslint-visitor-keys "^3.3.0" - espree "^9.3.2" + espree "^9.4.0" esquery "^1.4.0" esutils "^2.0.2" fast-deep-equal "^3.1.3" file-entry-cache "^6.0.1" - functional-red-black-tree "^1.0.1" - glob-parent "^6.0.1" + find-up "^5.0.0" + glob-parent "^6.0.2" globals "^13.15.0" + grapheme-splitter "^1.0.4" ignore "^5.2.0" import-fresh "^3.0.0" imurmurhash "^0.1.4" is-glob "^4.0.0" + is-path-inside "^3.0.3" + js-sdsl "^4.1.4" js-yaml "^4.1.0" json-stable-stringify-without-jsonify "^1.0.1" levn "^0.4.1" @@ -627,14 +743,13 @@ eslint@^8.20.0: strip-ansi "^6.0.1" strip-json-comments "^3.1.0" text-table "^0.2.0" - v8-compile-cache "^2.0.3" -espree@^9.3.2: - version "9.3.2" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.3.2.tgz#f58f77bd334731182801ced3380a8cc859091596" - integrity sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA== +espree@^9.4.0: + version "9.4.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.4.0.tgz#cd4bc3d6e9336c433265fc0aa016fc1aaf182f8a" + integrity sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw== dependencies: - acorn "^8.7.1" + acorn "^8.8.0" acorn-jsx "^5.3.2" eslint-visitor-keys "^3.3.0" @@ -662,6 +777,33 @@ esutils@^2.0.2: resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== +eventemitter2@6.4.7: + version "6.4.7" + resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-6.4.7.tgz#a7f6c4d7abf28a14c1ef3442f21cb306a054271d" + integrity sha512-tYUSVOGeQPKt/eC1ABfhHy5Xd96N3oIijJvN3O9+TsC28T5V9yX9oEfEK5faP0EFSNVOG97qtAS68GBrQB2hDg== + +execa@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-4.1.0.tgz#4e5491ad1572f2f17a77d388c6c857135b22847a" + integrity sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA== + dependencies: + cross-spawn "^7.0.0" + get-stream "^5.0.0" + human-signals "^1.1.1" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.0" + onetime "^5.1.0" + signal-exit "^3.0.2" + strip-final-newline "^2.0.0" + +executable@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/executable/-/executable-4.1.1.tgz#41532bff361d3e57af4d763b70582db18f5d133c" + integrity sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg== + dependencies: + pify "^2.2.0" + extend@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" @@ -703,6 +845,13 @@ fast-levenshtein@^2.0.6: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== +fastq@^1.6.0: + version "1.13.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" + integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== + dependencies: + reusify "^1.0.4" + fd-slicer@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" @@ -710,6 +859,13 @@ fd-slicer@~1.1.0: dependencies: pend "~1.2.0" +figures@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" + integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== + dependencies: + escape-string-regexp "^1.0.5" + file-entry-cache@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" @@ -717,11 +873,6 @@ file-entry-cache@^6.0.1: dependencies: flat-cache "^3.0.4" -file-uri-to-path@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" - integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== - fill-range@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" @@ -729,7 +880,7 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" -find-up@5.0.0: +find-up@5.0.0, find-up@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== @@ -737,7 +888,7 @@ find-up@5.0.0: locate-path "^6.0.0" path-exists "^4.0.0" -find-up@^4.0.0: +find-up@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== @@ -759,9 +910,9 @@ flat@^5.0.2: integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== flatted@^3.1.0: - version "3.2.6" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.6.tgz#022e9218c637f9f3fc9c35ab9c9193f05add60b2" - integrity sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ== + version "3.2.7" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787" + integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== forever-agent@~0.6.1: version "0.6.1" @@ -777,12 +928,7 @@ form-data@~2.3.2: combined-stream "^1.0.6" mime-types "^2.1.12" -fs-constants@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" - integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== - -fs-extra@^10.0.0: +fs-extra@^10.0.0, fs-extra@^10.0.1: version "10.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ== @@ -791,6 +937,25 @@ fs-extra@^10.0.0: jsonfile "^6.0.1" universalify "^2.0.0" +fs-extra@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" + integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw== + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-extra@^9.1.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" + integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== + dependencies: + at-least-node "^1.0.0" + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" @@ -806,64 +971,24 @@ fsu@^1.1.1: resolved "https://registry.yarnpkg.com/fsu/-/fsu-1.1.1.tgz#bd36d3579907c59d85b257a75b836aa9e0c31834" integrity sha512-xQVsnjJ/5pQtcKh+KjUoZGzVWn4uNkchxTF6Lwjr4Gf7nQr8fmUfhKJ62zE77+xQg9xnxi5KUps7XGs+VC986A== -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - -function.prototype.name@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.5.tgz#cce0505fe1ffb80503e6f9e46cc64e46a12a9621" - integrity sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.0" - functions-have-names "^1.2.2" - -functional-red-black-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g== - -functions-have-names@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" - integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== - -get-caller-file@^2.0.5: +get-caller-file@^2.0.1, get-caller-file@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -get-func-name@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" - integrity sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig== - -get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.2.tgz#336975123e05ad0b7ba41f152ee4aadbea6cf598" - integrity sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA== - dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.3" - -get-stream@^5.1.0: +get-stream@^5.0.0, get-stream@^5.1.0: version "5.2.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== dependencies: pump "^3.0.0" -get-symbol-description@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" - integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== +getos@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/getos/-/getos-3.2.1.tgz#0134d1f4e00eb46144c5a9c0ac4dc087cbb27dc5" + integrity sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q== dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.1" + async "^3.2.0" getpass@^0.1.1: version "0.1.7" @@ -872,7 +997,7 @@ getpass@^0.1.1: dependencies: assert-plus "^1.0.0" -glob-parent@^6.0.1: +glob-parent@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== @@ -898,7 +1023,7 @@ glob@7.2.0: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.1.3: +glob@^7.1.3, glob@^7.1.6: version "7.2.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== @@ -910,10 +1035,22 @@ glob@^7.1.3: once "^1.3.0" path-is-absolute "^1.0.0" +global-dirs@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-3.0.0.tgz#70a76fe84ea315ab37b1f5576cbde7d48ef72686" + integrity sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA== + dependencies: + ini "2.0.0" + +globals@^11.12.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + globals@^13.15.0: - version "13.16.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.16.0.tgz#9be4aca28f311aaeb974ea54978ebbb5e35ce46a" - integrity sha512-A1lrQfpNF+McdPOnnFqY3kSN0AFTy485bTi1bkLk4mVPODIUEcSfhHgRqA+QdXPksrSTTztYXx37NFV+GpGk3Q== + version "13.17.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.17.0.tgz#902eb1e680a41da93945adbdcb5a9f361ba69bd4" + integrity sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw== dependencies: type-fest "^0.20.2" @@ -922,86 +1059,34 @@ graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - integrity sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q== - -har-validator@~5.1.3: - version "5.1.5" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" - integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== - dependencies: - ajv "^6.12.3" - har-schema "^2.0.0" - -has-bigints@^1.0.1, has-bigints@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" - integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== +grapheme-splitter@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" + integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== has-flag@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -has-property-descriptors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" - integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== - dependencies: - get-intrinsic "^1.1.1" - -has-symbols@^1.0.1, has-symbols@^1.0.2, has-symbols@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" - integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== - -has-tostringtag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" - integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== - dependencies: - has-symbols "^1.0.2" - -has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - he@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== -hosted-git-info@^2.1.4: - version "2.8.9" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" - integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== - -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - integrity sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ== +http-signature@~1.3.6: + version "1.3.6" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.3.6.tgz#cb6fbfdf86d1c974f343be94e87f7fc128662cf9" + integrity sha512-3adrsD6zqo4GsTqtO7FyrejHNv+NgiIfAfv68+jVlFmSr9OGy7zrxONceFRLKvnnZA5jbxQBX1u9PpB6Wi32Gw== dependencies: assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" + jsprim "^2.0.2" + sshpk "^1.14.1" -https-proxy-agent@5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" - integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== - dependencies: - agent-base "6" - debug "4" +human-signals@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" + integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== ieee754@^1.1.13: version "1.2.1" @@ -1026,6 +1111,11 @@ imurmurhash@^0.1.4: resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== +indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== + inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" @@ -1034,31 +1124,15 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@^2.0.3, inherits@^2.0.4: +inherits@2: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== -internal-slot@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" - integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== - dependencies: - get-intrinsic "^1.1.0" - has "^1.0.3" - side-channel "^1.0.4" - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== - -is-bigint@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" - integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== - dependencies: - has-bigints "^1.0.1" +ini@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ini/-/ini-2.0.0.tgz#e5fd556ecdd5726be978fa1001862eacb0a94bc5" + integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA== is-binary-path@~2.1.0: version "2.1.0" @@ -1067,32 +1141,12 @@ is-binary-path@~2.1.0: dependencies: binary-extensions "^2.0.0" -is-boolean-object@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" - integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-callable@^1.1.4, is-callable@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" - integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w== - -is-core-module@^2.9.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.9.0.tgz#e1c34429cd51c6dd9e09e0799e396e27b19a9c69" - integrity sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A== - dependencies: - has "^1.0.3" - -is-date-object@^1.0.1: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" - integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== +is-ci@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-3.0.1.tgz#db6ecbed1bd659c43dac0f45661e7674103d1867" + integrity sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ== dependencies: - has-tostringtag "^1.0.0" + ci-info "^3.2.0" is-extglob@^2.1.1: version "2.1.1" @@ -1111,56 +1165,33 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" -is-negative-zero@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" - integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== - -is-number-object@^1.0.4: - version "1.0.7" - resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc" - integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== +is-installed-globally@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.4.0.tgz#9a0fd407949c30f86eb6959ef1b7994ed0b7b520" + integrity sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ== dependencies: - has-tostringtag "^1.0.0" + global-dirs "^3.0.0" + is-path-inside "^3.0.2" is-number@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== +is-path-inside@^3.0.2, is-path-inside@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + is-plain-obj@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== -is-regex@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" - integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-shared-array-buffer@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" - integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== - dependencies: - call-bind "^1.0.2" - -is-string@^1.0.5, is-string@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" - integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== - dependencies: - has-tostringtag "^1.0.0" - -is-symbol@^1.0.2, is-symbol@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" - integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== - dependencies: - has-symbols "^1.0.2" +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== is-typedarray@~1.0.0: version "1.0.0" @@ -1172,13 +1203,6 @@ is-unicode-supported@^0.1.0: resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== -is-weakref@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" - integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== - dependencies: - call-bind "^1.0.2" - isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -1189,6 +1213,11 @@ isstream@~0.1.2: resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g== +js-sdsl@^4.1.4: + version "4.1.5" + resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.1.5.tgz#1ff1645e6b4d1b028cd3f862db88c9d887f26e2a" + integrity sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q== + "js-tokens@^3.0.0 || ^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -1206,11 +1235,6 @@ jsbn@~0.1.0: resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" integrity sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg== -json-parse-better-errors@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" - integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== - json-schema-traverse@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" @@ -1231,6 +1255,13 @@ json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg== + optionalDependencies: + graceful-fs "^4.1.6" + jsonfile@^6.0.1: version "6.1.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" @@ -1240,20 +1271,20 @@ jsonfile@^6.0.1: optionalDependencies: graceful-fs "^4.1.6" -jsprim@^1.2.2: - version "1.4.2" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.2.tgz#712c65533a15c878ba59e9ed5f0e26d5b77c5feb" - integrity sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw== +jsprim@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-2.0.2.tgz#77ca23dbcd4135cd364800d22ff82c2185803d4d" + integrity sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ== dependencies: assert-plus "1.0.0" extsprintf "1.3.0" json-schema "0.4.0" verror "1.10.0" -jwt-decode@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/jwt-decode/-/jwt-decode-3.1.2.tgz#3fb319f3675a2df0c2895c8f5e9fa4b67b04ed59" - integrity sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A== +lazy-ass@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/lazy-ass/-/lazy-ass-1.6.0.tgz#7999655e8646c17f089fdd187d150d3324d54513" + integrity sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw== levn@^0.4.1: version "0.4.1" @@ -1263,15 +1294,19 @@ levn@^0.4.1: prelude-ls "^1.2.1" type-check "~0.4.0" -load-json-file@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" - integrity sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw== - dependencies: - graceful-fs "^4.1.2" - parse-json "^4.0.0" - pify "^3.0.0" - strip-bom "^3.0.0" +listr2@^3.8.3: + version "3.14.0" + resolved "https://registry.yarnpkg.com/listr2/-/listr2-3.14.0.tgz#23101cc62e1375fd5836b248276d1d2b51fdbe9e" + integrity sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g== + dependencies: + cli-truncate "^2.1.0" + colorette "^2.0.16" + log-update "^4.0.0" + p-map "^4.0.0" + rfdc "^1.3.0" + rxjs "^7.5.1" + through "^2.3.8" + wrap-ansi "^7.0.0" locate-path@^5.0.0: version "5.0.0" @@ -1312,12 +1347,17 @@ lodash.merge@^4.6.2: resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== +lodash.once@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" + integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg== + lodash@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== -log-symbols@4.1.0: +log-symbols@4.1.0, log-symbols@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== @@ -1325,6 +1365,16 @@ log-symbols@4.1.0: chalk "^4.1.0" is-unicode-supported "^0.1.0" +log-update@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/log-update/-/log-update-4.0.0.tgz#589ecd352471f2a1c0c570287543a64dfd20e0a1" + integrity sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg== + dependencies: + ansi-escapes "^4.3.0" + cli-cursor "^3.1.0" + slice-ansi "^4.0.0" + wrap-ansi "^6.2.0" + loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" @@ -1332,17 +1382,17 @@ loose-envify@^1.4.0: dependencies: js-tokens "^3.0.0 || ^4.0.0" -loupe@^2.3.1: - version "2.3.4" - resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.4.tgz#7e0b9bffc76f148f9be769cb1321d3dcf3cb25f3" - integrity sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ== +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== dependencies: - get-func-name "^2.0.0" + yallist "^4.0.0" -memorystream@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" - integrity sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw== +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== mime-db@1.52.0: version "1.52.0" @@ -1356,6 +1406,11 @@ mime-types@^2.1.12, mime-types@~2.1.19: dependencies: mime-db "1.52.0" +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + minimatch@5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" @@ -1370,17 +1425,16 @@ minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: dependencies: brace-expansion "^1.1.7" -mkdirp-classic@^0.5.2: - version "0.5.3" - resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" - integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== +minimist@^1.2.6: + version "1.2.7" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.7.tgz#daa1c4d91f507390437c6a8bc01078e7000c4d18" + integrity sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g== -mocha@^10.0.0: - version "10.0.0" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.0.0.tgz#205447d8993ec755335c4b13deba3d3a13c4def9" - integrity sha512-0Wl+elVUD43Y0BqPZBzZt8Tnkw9CMUdNYnUsTfOM1vuhJVZL+kiesFYsqwBkEEuEixaiPe5ZQdqDgX2jddhmoA== +mocha@^10.1.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.1.0.tgz#dbf1114b7c3f9d0ca5de3133906aea3dfc89ef7a" + integrity sha512-vUF7IYxEoN7XhQpFLxQAEMtE4W91acW4B6En9l97MwE9stL1A9gusXfoHZCLVHDUJ/7V5+lbCM6yMqzo5vNymg== dependencies: - "@ungap/promise-all-settled" "1.1.2" ansi-colors "4.1.1" browser-stdout "1.3.1" chokidar "3.5.3" @@ -1403,6 +1457,15 @@ mocha@^10.0.0: yargs-parser "20.2.4" yargs-unparser "2.0.0" +mochawesome-merge@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/mochawesome-merge/-/mochawesome-merge-4.2.1.tgz#484e5c500dd5d88b33adb440e6dfef80d9109a18" + integrity sha512-G7+LqIKgixShKG4FyWDn1PIrzpKEwCofrJip/VzdqghNGqZl4S5MNoXx5YDfk9KLe+pr4qGa1TOzCc/oVw/8Kw== + dependencies: + fs-extra "^7.0.1" + glob "^7.1.6" + yargs "^15.3.1" + mochawesome-report-generator@^6.2.0: version "6.2.0" resolved "https://registry.yarnpkg.com/mochawesome-report-generator/-/mochawesome-report-generator-6.2.0.tgz#65a30a11235ba7a68e1cf0ca1df80d764b93ae78" @@ -1437,17 +1500,12 @@ mochawesome@^7.1.3: strip-ansi "^6.0.1" uuid "^8.3.2" -moment@^2.29.3: - version "2.29.4" - resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.4.tgz#3dbe052889fe7c1b2ed966fcb3a77328964ef108" - integrity sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w== - ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@2.1.3: +ms@2.1.3, ms@^2.1.1: version "2.1.3" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== @@ -1462,83 +1520,23 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== -nice-try@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" - integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== - -node-addon-api@^1.7.1: - version "1.7.2" - resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-1.7.2.tgz#3df30b95720b53c24e59948b49532b662444f54d" - integrity sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg== - -node-fetch@2.6.7: - version "2.6.7" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" - integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== - dependencies: - whatwg-url "^5.0.0" - -normalize-package-data@^2.3.2: - version "2.5.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" - integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== - dependencies: - hosted-git-info "^2.1.4" - resolve "^1.10.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" - normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== -npm-run-all@^4.1.5: - version "4.1.5" - resolved "https://registry.yarnpkg.com/npm-run-all/-/npm-run-all-4.1.5.tgz#04476202a15ee0e2e214080861bff12a51d98fba" - integrity sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ== +npm-run-path@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== dependencies: - ansi-styles "^3.2.1" - chalk "^2.4.1" - cross-spawn "^6.0.5" - memorystream "^0.3.1" - minimatch "^3.0.4" - pidtree "^0.3.0" - read-pkg "^3.0.0" - shell-quote "^1.6.1" - string.prototype.padend "^3.0.0" - -oauth-sign@~0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" - integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== + path-key "^3.0.0" object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== -object-inspect@^1.12.0, object-inspect@^1.9.0: - version "1.12.2" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" - integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== - -object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - -object.assign@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" - integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - has-symbols "^1.0.1" - object-keys "^1.1.1" - once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" @@ -1546,6 +1544,13 @@ once@^1.3.0, once@^1.3.1, once@^1.4.0: dependencies: wrappy "1" +onetime@^5.1.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + opener@^1.5.2: version "1.5.2" resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.2.tgz#5d37e1f35077b9dcac4301372271afdeb2a13598" @@ -1563,6 +1568,11 @@ optionator@^0.9.1: type-check "^0.4.0" word-wrap "^1.2.3" +ospath@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/ospath/-/ospath-1.2.2.tgz#1276639774a3f8ef2572f7fe4280e0ea4550c07b" + integrity sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA== + p-limit@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" @@ -1591,16 +1601,18 @@ p-locate@^5.0.0: dependencies: p-limit "^3.0.2" +p-map@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" + integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== + dependencies: + aggregate-error "^3.0.0" + p-try@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== -pako@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pako/-/pako-2.0.4.tgz#6cebc4bbb0b6c73b0d5b8d7e8476e2b2fbea576d" - integrity sha512-v8tweI900AUkZN6heMU/4Uy4cXRc2AYNRggVmTR+dEncawDJgCdLMximOVA2p4qO57WMynangsfGRb5WD6L1Bg== - parent-module@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" @@ -1608,14 +1620,6 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" -parse-json@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" - integrity sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw== - dependencies: - error-ex "^1.3.1" - json-parse-better-errors "^1.0.1" - path-exists@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" @@ -1626,33 +1630,11 @@ path-is-absolute@^1.0.0: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== -path-key@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - integrity sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw== - -path-key@^3.1.0: +path-key@^3.0.0, path-key@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== -path-parse@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" - integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== - -path-type@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" - integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== - dependencies: - pify "^3.0.0" - -pathval@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" - integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== - pend@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" @@ -1668,22 +1650,10 @@ picomatch@^2.0.4, picomatch@^2.2.1: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== -pidtree@^0.3.0: - version "0.3.1" - resolved "https://registry.yarnpkg.com/pidtree/-/pidtree-0.3.1.tgz#ef09ac2cc0533df1f3250ccf2c4d366b0d12114a" - integrity sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA== - -pify@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" - integrity sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg== - -pkg-dir@4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" - integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== - dependencies: - find-up "^4.0.0" +pify@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== prelude-ls@^1.2.1: version "1.2.1" @@ -1695,10 +1665,10 @@ prettier@^2.7.1: resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.7.1.tgz#e235806850d057f97bb08368a4f7d899f7760c64" integrity sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g== -progress@2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" - integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== +pretty-bytes@^5.6.0: + version "5.6.0" + resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb" + integrity sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg== prop-types@^15.7.2: version "15.8.1" @@ -1709,10 +1679,10 @@ prop-types@^15.7.2: object-assign "^4.1.1" react-is "^16.13.1" -proxy-from-env@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" - integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== +proxy-from-env@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.0.0.tgz#33c50398f70ea7eb96d21f7b817630a55791c7ee" + integrity sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A== psl@^1.1.28: version "1.9.0" @@ -1732,29 +1702,16 @@ punycode@^2.1.0, punycode@^2.1.1: resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== -puppeteer@^15.4.0: - version "15.4.0" - resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-15.4.0.tgz#31f043ee64cc4e1b5cbe99ad900653aab4afb186" - integrity sha512-wxJRbofjaycCaQ9fhABlToJobrjxlABiFi6NvdkOPVJMYFblxDlDTjkg+b6bZYi7xN+lEXn84GBZsA5DYb3wfw== - dependencies: - cross-fetch "3.1.5" - debug "4.3.4" - devtools-protocol "0.0.1011705" - extract-zip "2.0.1" - https-proxy-agent "5.0.1" - pkg-dir "4.2.0" - progress "2.0.3" - proxy-from-env "1.1.0" - rimraf "3.0.2" - tar-fs "2.1.1" - unbzip2-stream "1.4.3" - ws "8.8.0" - qs@~6.5.2: version "6.5.3" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad" integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA== +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + randombytes@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" @@ -1767,24 +1724,6 @@ react-is@^16.13.1: resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== -read-pkg@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" - integrity sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA== - dependencies: - load-json-file "^4.0.0" - normalize-package-data "^2.3.2" - path-type "^3.0.0" - -readable-stream@^3.1.1, readable-stream@^3.4.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" - integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - readdirp@~3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" @@ -1792,73 +1731,73 @@ readdirp@~3.6.0: dependencies: picomatch "^2.2.1" -regexp.prototype.flags@^1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac" - integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - functions-have-names "^1.2.2" - regexpp@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== -request@^2.88.2: - version "2.88.2" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" - integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== +request-progress@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/request-progress/-/request-progress-3.0.0.tgz#4ca754081c7fec63f505e4faa825aa06cd669dbe" + integrity sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg== dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.8.0" - caseless "~0.12.0" - combined-stream "~1.0.6" - extend "~3.0.2" - forever-agent "~0.6.1" - form-data "~2.3.2" - har-validator "~5.1.3" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.19" - oauth-sign "~0.9.0" - performance-now "^2.1.0" - qs "~6.5.2" - safe-buffer "^5.1.2" - tough-cookie "~2.5.0" - tunnel-agent "^0.6.0" - uuid "^3.3.2" + throttleit "^1.0.0" require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== +require-main-filename@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" + integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== + resolve-from@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== -resolve@^1.10.0: - version "1.22.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" - integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== +restore-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" + integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== dependencies: - is-core-module "^2.9.0" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" + onetime "^5.1.0" + signal-exit "^3.0.2" + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -rimraf@3.0.2, rimraf@^3.0.2: +rfdc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" + integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== + +rimraf@^3.0.0, rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== dependencies: glob "^7.1.3" -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@~5.2.0: +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +rxjs@^7.5.1: + version "7.5.7" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.7.tgz#2ec0d57fdc89ece220d2e702730ae8f1e49def39" + integrity sha512-z9MzKh/UcOqB3i20H6rtrlaE/CgjLOvheWK/9ILrbhROGTweAi1BaFsTT9FbwZi5Trr1qNRs+MXkhmR06awzQA== + dependencies: + tslib "^2.1.0" + +safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -1868,20 +1807,17 @@ safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -saml-encoder-decoder-js@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/saml-encoder-decoder-js/-/saml-encoder-decoder-js-1.0.1.tgz#5b945ef57fe063d62f558800bc6a1747c51c9059" - integrity sha512-CXzXAIKn5VQ+41YaF3s/8uYxB8adMv7ir8O0nOv+epOyeAjZqWH7KJowBPYo9prBvdLQB51kSUL8YRIY9zgy8g== - sax@>=0.6.0: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== -"semver@2 || 3 || 4 || 5", semver@^5.5.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== +semver@^7.3.2: + version "7.3.8" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798" + integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A== + dependencies: + lru-cache "^6.0.0" serialize-javascript@6.0.0: version "6.0.0" @@ -1890,12 +1826,10 @@ serialize-javascript@6.0.0: dependencies: randombytes "^2.1.0" -shebang-command@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" - integrity sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg== - dependencies: - shebang-regex "^1.0.0" +set-blocking@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== shebang-command@^2.0.0: version "2.0.0" @@ -1904,106 +1838,35 @@ shebang-command@^2.0.0: dependencies: shebang-regex "^3.0.0" -shebang-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" - integrity sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ== - shebang-regex@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -shell-quote@^1.6.1: - version "1.7.3" - resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.3.tgz#aa40edac170445b9a431e17bb62c0b881b9c4123" - integrity sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw== - -should-equal@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/should-equal/-/should-equal-2.0.0.tgz#6072cf83047360867e68e98b09d71143d04ee0c3" - integrity sha512-ZP36TMrK9euEuWQYBig9W55WPC7uo37qzAEmbjHz4gfyuXrEUgF8cUvQVO+w+d3OMfPvSRQJ22lSm8MQJ43LTA== - dependencies: - should-type "^1.4.0" - -should-format@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/should-format/-/should-format-3.0.3.tgz#9bfc8f74fa39205c53d38c34d717303e277124f1" - integrity sha512-hZ58adtulAk0gKtua7QxevgUaXTTXxIi8t41L3zo9AHvjXO1/7sdLECuHeIN2SRtYXpNkmhoUP2pdeWgricQ+Q== - dependencies: - should-type "^1.3.0" - should-type-adaptors "^1.0.1" - -should-type-adaptors@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/should-type-adaptors/-/should-type-adaptors-1.1.0.tgz#401e7f33b5533033944d5cd8bf2b65027792e27a" - integrity sha512-JA4hdoLnN+kebEp2Vs8eBe9g7uy0zbRo+RMcU0EsNy+R+k049Ki+N5tT5Jagst2g7EAja+euFuoXFCa8vIklfA== - dependencies: - should-type "^1.3.0" - should-util "^1.0.0" - -should-type@^1.3.0, should-type@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/should-type/-/should-type-1.4.0.tgz#0756d8ce846dfd09843a6947719dfa0d4cff5cf3" - integrity sha512-MdAsTu3n25yDbIe1NeN69G4n6mUnJGtSJHygX3+oN0ZbO3DTiATnf7XnYJdGT42JCXurTb1JI0qOBR65shvhPQ== - -should-util@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/should-util/-/should-util-1.0.1.tgz#fb0d71338f532a3a149213639e2d32cbea8bcb28" - integrity sha512-oXF8tfxx5cDk8r2kYqlkUJzZpDBqVY/II2WhvU0n9Y3XYvAYRmeaf1PvvIvTgPnv4KJ+ES5M0PyDq5Jp+Ygy2g== - -should@^13.2.3: - version "13.2.3" - resolved "https://registry.yarnpkg.com/should/-/should-13.2.3.tgz#96d8e5acf3e97b49d89b51feaa5ae8d07ef58f10" - integrity sha512-ggLesLtu2xp+ZxI+ysJTmNjh2U0TsC+rQ/pfED9bUZZ4DKefP27D+7YJVVTvKsmjLpIi9jAa7itwDGkDDmt1GQ== - dependencies: - should-equal "^2.0.0" - should-format "^3.0.3" - should-type "^1.4.0" - should-type-adaptors "^1.0.1" - should-util "^1.0.0" +signal-exit@^3.0.2: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== -side-channel@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" - integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== - dependencies: - call-bind "^1.0.0" - get-intrinsic "^1.0.2" - object-inspect "^1.9.0" - -sleep-promise@^9.1.0: - version "9.1.0" - resolved "https://registry.yarnpkg.com/sleep-promise/-/sleep-promise-9.1.0.tgz#101ebe65700bcd184709da95d960967b02b79d03" - integrity sha512-UHYzVpz9Xn8b+jikYSD6bqvf754xL2uBUzDFwiU6NcdZeifPr6UfgU43xpkPu67VMS88+TI2PSI7Eohgqf2fKA== - -spdx-correct@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" - integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== +slice-ansi@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-3.0.0.tgz#31ddc10930a1b7e0b67b08c96c2f49b77a789787" + integrity sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ== dependencies: - spdx-expression-parse "^3.0.0" - spdx-license-ids "^3.0.0" - -spdx-exceptions@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" - integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" -spdx-expression-parse@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" - integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== +slice-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" + integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== dependencies: - spdx-exceptions "^2.1.0" - spdx-license-ids "^3.0.0" - -spdx-license-ids@^3.0.0: - version "3.0.11" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz#50c0d8c40a14ec1bf449bae69a0ea4685a9d9f95" - integrity sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g== + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" -sshpk@^1.7.0: +sshpk@^1.14.1: version "1.17.0" resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.17.0.tgz#578082d92d4fe612b13007496e543fa0fbcbe4c5" integrity sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ== @@ -2027,40 +1890,6 @@ string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -string.prototype.padend@^3.0.0: - version "3.1.3" - resolved "https://registry.yarnpkg.com/string.prototype.padend/-/string.prototype.padend-3.1.3.tgz#997a6de12c92c7cb34dc8a201a6c53d9bd88a5f1" - integrity sha512-jNIIeokznm8SD/TZISQsZKYu7RJyheFNt84DUPrh482GC8RVp2MKqm2O5oBRdGxbDQoXrhhWtPIWQOiy20svUg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.1" - -string.prototype.trimend@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz#914a65baaab25fbdd4ee291ca7dde57e869cb8d0" - integrity sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.19.5" - -string.prototype.trimstart@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz#5466d93ba58cfa2134839f81d7f42437e8c01fef" - integrity sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.19.5" - -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" @@ -2068,30 +1897,23 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== strip-json-comments@3.1.1, strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== -supports-color@8.1.1: +supports-color@8.1.1, supports-color@^8.1.1: version "8.1.1" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== dependencies: has-flag "^4.0.0" -supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - supports-color@^7.1.0: version "7.2.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" @@ -2099,39 +1921,6 @@ supports-color@^7.1.0: dependencies: has-flag "^4.0.0" -supports-preserve-symlinks-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" - integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== - -system-sleep@^1.3.7: - version "1.3.7" - resolved "https://registry.yarnpkg.com/system-sleep/-/system-sleep-1.3.7.tgz#d1de1acbf6e8ab3f1b852de03eb8540d1bc8b952" - integrity sha512-0Bd7sdWpO+UNLwPr7I4fhmaYf5RARbx4LQPgEPHVqU+uYc1C7FMfxyEWZlJXHpcGmtSR7KeR9npNpool+s8TvQ== - dependencies: - deasync-promise "1.0.1" - -tar-fs@2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" - integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== - dependencies: - chownr "^1.1.1" - mkdirp-classic "^0.5.2" - pump "^3.0.0" - tar-stream "^2.1.4" - -tar-stream@^2.1.4: - version "2.2.0" - resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" - integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== - dependencies: - bl "^4.0.3" - end-of-stream "^1.4.1" - fs-constants "^1.0.0" - inherits "^2.0.3" - readable-stream "^3.1.1" - tcomb-validation@^3.3.0: version "3.4.1" resolved "https://registry.yarnpkg.com/tcomb-validation/-/tcomb-validation-3.4.1.tgz#a7696ec176ce56a081d9e019f8b732a5a8894b65" @@ -2149,11 +1938,23 @@ text-table@^0.2.0: resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== +throttleit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-1.0.0.tgz#9e785836daf46743145a5984b6268d828528ac6c" + integrity sha512-rkTVqu6IjfQ/6+uNuuc3sZek4CEYxTJom3IktzgdSxcZqdARuebbA/f4QmAxMQIxqq9ZLEUkSYqvuk1I6VKq4g== + through@^2.3.8: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== +tmp@~0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" + integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== + dependencies: + rimraf "^3.0.0" + to-regex-range@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" @@ -2169,10 +1970,10 @@ tough-cookie@~2.5.0: psl "^1.1.28" punycode "^2.1.1" -tr46@~0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" - integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== +tslib@^2.1.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" + integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== tunnel-agent@^0.6.0: version "0.6.0" @@ -2193,39 +1994,36 @@ type-check@^0.4.0, type-check@~0.4.0: dependencies: prelude-ls "^1.2.1" -type-detect@^4.0.0, type-detect@^4.0.5: - version "4.0.8" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" - integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== - type-fest@^0.20.2: version "0.20.2" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== -unbox-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" - integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== - dependencies: - call-bind "^1.0.2" - has-bigints "^1.0.2" - has-symbols "^1.0.3" - which-boxed-primitive "^1.0.2" +type-fest@^0.21.3: + version "0.21.3" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== -unbzip2-stream@1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz#b0da04c4371311df771cdc215e87f2130991ace7" - integrity sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg== - dependencies: - buffer "^5.2.1" - through "^2.3.8" +typescript@^4.8.4: + version "4.8.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.4.tgz#c464abca159669597be5f96b8943500b238e60e6" + integrity sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ== + +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== universalify@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== +untildify@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" + integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== + uri-js@^4.2.2: version "4.4.1" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" @@ -2233,34 +2031,11 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" -util-deprecate@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== - -uuid@^3.3.2: - version "3.4.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" - integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== - uuid@^8.3.2: version "8.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== -v8-compile-cache@^2.0.3: - version "2.3.0" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" - integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== - -validate-npm-package-license@^3.0.1: - version "3.0.4" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" - integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== - dependencies: - spdx-correct "^3.0.0" - spdx-expression-parse "^3.0.0" - validator@^13.6.0: version "13.7.0" resolved "https://registry.yarnpkg.com/validator/-/validator-13.7.0.tgz#4f9658ba13ba8f3d82ee881d3516489ea85c0857" @@ -2275,36 +2050,10 @@ verror@1.10.0: core-util-is "1.0.2" extsprintf "^1.2.0" -webidl-conversions@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" - integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== - -whatwg-url@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" - integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== - dependencies: - tr46 "~0.0.3" - webidl-conversions "^3.0.0" - -which-boxed-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" - integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== - dependencies: - is-bigint "^1.0.1" - is-boolean-object "^1.1.0" - is-number-object "^1.0.4" - is-string "^1.0.5" - is-symbol "^1.0.3" - -which@^1.2.9: - version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== - dependencies: - isexe "^2.0.0" +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + integrity sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q== which@^2.0.1: version "2.0.2" @@ -2323,6 +2072,15 @@ workerpool@6.2.1: resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== +wrap-ansi@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" + integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" @@ -2337,11 +2095,6 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== -ws@8.8.0: - version "8.8.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.8.0.tgz#8e71c75e2f6348dbf8d78005107297056cb77769" - integrity sha512-JDAgSYQ1ksuwqfChJusw1LSJ8BizJ2e/vVu5Lxjq3YvNJNlROv1ui4i+c/kUUrPheBvQl4c5UbERhTwKa6QBJQ== - xml2js@^0.4.23: version "0.4.23" resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66" @@ -2350,35 +2103,48 @@ xml2js@^0.4.23: sax ">=0.6.0" xmlbuilder "~11.0.0" -xml2json-light@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/xml2json-light/-/xml2json-light-1.0.6.tgz#111687710a2b01fbd2fe18f418adf511de547f34" - integrity sha512-6CSibpteBS4B8/fzJaj6TDtWatIlonSFfVVK3TLM23mlTOxkMgVA4b2FaGeTIrrhOMdDZ8X1/dvo4mfBtsU4yw== - xmlbuilder@~11.0.0: version "11.0.1" resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== +y18n@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" + integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== + y18n@^5.0.5: version "5.0.8" resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + yargs-parser@20.2.4: version "20.2.4" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== +yargs-parser@^18.1.2: + version "18.1.3" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0" + integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + yargs-parser@^20.2.2: version "20.2.9" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== yargs-parser@^21.0.0: - version "21.0.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.0.1.tgz#0267f286c877a4f0f728fceb6f8a3e4cb95c6e35" - integrity sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg== + version "21.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" + integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== yargs-unparser@2.0.0: version "2.0.0" @@ -2403,12 +2169,29 @@ yargs@16.2.0: y18n "^5.0.5" yargs-parser "^20.2.2" +yargs@^15.3.1: + version "15.4.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8" + integrity sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A== + dependencies: + cliui "^6.0.0" + decamelize "^1.2.0" + find-up "^4.1.0" + get-caller-file "^2.0.1" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^4.2.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^18.1.2" + yargs@^17.2.1: - version "17.5.1" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.5.1.tgz#e109900cab6fcb7fd44b1d8249166feb0b36e58e" - integrity sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA== + version "17.6.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.6.0.tgz#e134900fc1f218bc230192bdec06a0a5f973e46c" + integrity sha512-8H/wTDqlSwoSnScvV2N/JHfLWOKuh5MVla9hqLjK3nsfyy6Y4kDSYSvkU5YCUEPOSnRXfIyx3Sq+B/IWudTo4g== dependencies: - cliui "^7.0.2" + cliui "^8.0.1" escalade "^3.1.1" get-caller-file "^2.0.5" require-directory "^2.1.1" diff --git a/siteminder-tests/.dockerignore b/siteminder-tests/.dockerignore deleted file mode 100644 index 080ae9a6..00000000 --- a/siteminder-tests/.dockerignore +++ /dev/null @@ -1,6 +0,0 @@ -results -screen_shots -node_modules -.prettierrc -.eslintrc -.dockerignore diff --git a/siteminder-tests/.eslintrc.yml b/siteminder-tests/.eslintrc.yml deleted file mode 100644 index df977a0f..00000000 --- a/siteminder-tests/.eslintrc.yml +++ /dev/null @@ -1,8 +0,0 @@ -env: - browser: true - commonjs: true - es2021: true -extends: eslint:recommended -parserOptions: - ecmaVersion: latest -rules: {} diff --git a/siteminder-tests/.mocharc.js b/siteminder-tests/.mocharc.js deleted file mode 100644 index 2942a3f5..00000000 --- a/siteminder-tests/.mocharc.js +++ /dev/null @@ -1,8 +0,0 @@ -'use strict'; - -module.exports = { - timeout: 20000, - diff: false, - reporter: 'mochawesome', - 'reporter-option': ['reportDir=results', 'reportFilename=siteminder-test', 'html=false'], -}; diff --git a/siteminder-tests/.prettierignore b/siteminder-tests/.prettierignore deleted file mode 100644 index 3c3629e6..00000000 --- a/siteminder-tests/.prettierignore +++ /dev/null @@ -1 +0,0 @@ -node_modules diff --git a/siteminder-tests/.prettierrc b/siteminder-tests/.prettierrc deleted file mode 100644 index 571e7952..00000000 --- a/siteminder-tests/.prettierrc +++ /dev/null @@ -1,11 +0,0 @@ -{ - "singleQuote": true, - "printWidth": 120, - "tabWidth": 2, - "useTabs": false, - "semi": true, - "quoteProps": "as-needed", - "trailingComma": "all", - "bracketSpacing": true, - "arrowParens": "always" -} diff --git a/siteminder-tests/Dockerfile b/siteminder-tests/Dockerfile deleted file mode 100644 index 566e6056..00000000 --- a/siteminder-tests/Dockerfile +++ /dev/null @@ -1,17 +0,0 @@ -FROM node:16.14.2-slim - -RUN apt-get update && apt-get install curl gnupg -y \ - && curl --location --silent https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \ - && sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list' \ - && apt-get update \ - && apt-get install google-chrome-stable -y --no-install-recommends \ - && rm -rf /var/lib/apt/lists/* - -COPY . /app/ - -WORKDIR /app - -RUN yarn install - -ENTRYPOINT [ "yarn" ] -CMD [ "test:html" ] diff --git a/siteminder-tests/config.js b/siteminder-tests/config.js deleted file mode 100755 index c95c3c15..00000000 --- a/siteminder-tests/config.js +++ /dev/null @@ -1,55 +0,0 @@ -require('dotenv').config(); - -const process = require('process'); - -const environment = process.env.ENVIRONMENT.toUpperCase() || 'DEV'; - -const cluster = process.env.CLUSTER.toUpperCase() || 'SILVER'; - -const fetchEnvParam = (param) => { - // Silver dev uses same credentials as test - if (cluster === 'SILVER' && environment === 'DEV') return eval(`process.env.TEST_${param}`); - return eval(`process.env.${environment}_${param}`); -}; - -module.exports = { - fetchSsoUrl: function (provider) { - let realm = eval(`process.env.${cluster}_${provider}_REALM`); - - if (cluster === 'SILVER') { - return `https://${ - process.env.ENVIRONMENT === 'prod' ? '' : process.env.ENVIRONMENT + '.' - }oidc.gov.bc.ca/auth/admin/${realm}/console/`; - } else { - return `https://${ - process.env.ENVIRONMENT === 'prod' ? '' : process.env.ENVIRONMENT + '.' - }loginproxy.gov.bc.ca/auth/admin/${realm}/console/`; - } - }, - idir_config: { - username: process.env.IDIR_USERNAME, - password: process.env.IDIR_PASSWORD, - user_identifier: process.env.IDIR_USER_IDENTIFIER, - display_name: process.env.IDIR_DISPLAYNAME, - email: process.env.IDIR_EMAIL, - firstname: process.env.IDIR_FIRSTNAME, - lastname: process.env.IDIR_LASTNAME, - }, - bceid_basic_config: { - username: fetchEnvParam('BCEID_BASIC_USERNAME'), - password: fetchEnvParam('BCEID_BASIC_PASSWORD'), - user_identifier: fetchEnvParam('BCEID_BASIC_USER_IDENTIFIER'), - display_name: fetchEnvParam('BCEID_BASIC_DISPLAYNAME'), - email: fetchEnvParam('BCEID_BASIC_EMAIL'), - }, - - bceid_business_config: { - username: fetchEnvParam('BCEID_BUSINESS_USERNAME'), - password: fetchEnvParam('BCEID_BUSINESS_PASSWORD'), - user_identifier: fetchEnvParam('BCEID_BUSINESS_USER_IDENTIFIER'), - display_name: fetchEnvParam('BCEID_BUSINESS_DISPLAYNAME'), - email: fetchEnvParam('BCEID_BUSINESS_EMAIL'), - guid: fetchEnvParam('BCEID_BUSINESS_GUID'), - legalname: fetchEnvParam('BCEID_BUSINESS_LEGALNAME'), - }, -}; diff --git a/siteminder-tests/docker-compose.yml b/siteminder-tests/docker-compose.yml deleted file mode 100644 index 24ca58b5..00000000 --- a/siteminder-tests/docker-compose.yml +++ /dev/null @@ -1,14 +0,0 @@ -version: '3.8' - -services: - siteminder-tests: - image: siteminder-tests:latest - container_name: siteminder-tests - environment: - ENVIRONMENT: ${ENVIRONMENT} - CLUSTER: ${CLUSTER} - build: - context: . - dockerfile: Dockerfile - volumes: - - ./results:/app/results diff --git a/siteminder-tests/package.json b/siteminder-tests/package.json deleted file mode 100644 index 2fec77bd..00000000 --- a/siteminder-tests/package.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "name": "test-mocha", - "version": "1.0.0", - "main": "index.js", - "license": "MIT", - "scripts": { - "test": "node ./node_modules/mocha/bin/mocha ./tests --no-diff", - "html": "marge results/siteminder-test.json --reportDir results -i -t \"SSO Siteminder Tests Report\"", - "test:html": "run-s --continue-on-error test html" - }, - "devDependencies": { - "eslint": "^8.20.0", - "prettier": "^2.7.1" - }, - "dependencies": { - "async": "^3.2.4", - "chai": "^4.3.6", - "delay": "^5.0.0", - "dotenv": "^16.0.1", - "jwt-decode": "^3.1.2", - "lodash": "^4.17.21", - "mocha": "^10.0.0", - "mochawesome": "^7.1.3", - "moment": "^2.29.3", - "npm-run-all": "^4.1.5", - "pako": "^2.0.4", - "puppeteer": "^15.4.0", - "request": "^2.88.2", - "saml-encoder-decoder-js": "^1.0.1", - "should": "^13.2.3", - "sleep-promise": "^9.1.0", - "system-sleep": "^1.3.7", - "xml2js": "^0.4.23", - "xml2json-light": "^1.0.6" - } -} diff --git a/siteminder-tests/tests/index.test.js b/siteminder-tests/tests/index.test.js deleted file mode 100644 index 853272cc..00000000 --- a/siteminder-tests/tests/index.test.js +++ /dev/null @@ -1,85 +0,0 @@ -const puppeteer = require('puppeteer'); -const process = require('process'); -const { testsite, screenShotsDir } = require('../util'); -const { idir_config, bceid_basic_config, bceid_business_config, fetchSsoUrl } = require('../config'); -const assert = require('assert'); -const { describe, it, beforeEach, afterEach } = require('mocha'); -const addContext = require('mochawesome/addContext'); - -describe('siteminder test suite', function () { - let browser; - let page; - beforeEach(async function () { - browser = await puppeteer.launch({ - headless: true, - args: ['--disable-gpu', '--disable-dev-shm-usage', '--disable-setuid-sandbox', '--no-sandbox'], - }); - page = await browser.newPage(); - await page.setViewport({ width: 800, height: 600 }); - }); - - afterEach(async function () { - await page.waitForTimeout(process.env.TIMEOUTSETTING); - await page.screenshot({ path: `${screenShotsDir}/${this.currentTest.title}.png` }); - await page.waitForTimeout(process.env.TIMEOUTSETTING); - await page.close(); - await browser.close(); - addContext(this, `assets/${this.currentTest.title}.png`); - }); - - it('idir', async function () { - const data = await testsite(fetchSsoUrl('IDIR'), idir_config.username, idir_config.password, 'IDIR', page); - assert.deepEqual(data.guid, idir_config.user_identifier, 'user_identifier'); - assert.deepEqual(data.display_name, idir_config.display_name, 'display_name'); - assert.deepEqual(data.username, idir_config.username, 'username'); - assert.deepEqual(data.email, idir_config.email, 'email'); - assert.deepEqual(data.firstname, idir_config.firstname, 'firstname'); - assert.deepEqual(data.lastname, idir_config.lastname, 'lastname'); - }); - - it('bceid-basic', async function () { - const data = await testsite( - fetchSsoUrl('BCEID_BASIC'), - bceid_basic_config.username, - bceid_basic_config.password, - 'BCEID_BASIC', - page, - ); - assert.deepEqual(data.guid, bceid_basic_config.user_identifier, 'user_identifier'); - assert.deepEqual(data.display_name, bceid_basic_config.display_name, 'display_name'); - assert.deepEqual(data.username, bceid_basic_config.username, 'username'); - assert.deepEqual(data.email, bceid_basic_config.email, 'email'); - }); - - it('bceid-business', async function () { - const data = await testsite( - fetchSsoUrl('BCEID_BUSINESS'), - bceid_business_config.username, - bceid_business_config.password, - 'BCEID_BUSINESS', - page, - ); - assert.deepEqual(data.guid, bceid_business_config.user_identifier, 'user_identifier'); - assert.deepEqual(data.display_name, bceid_business_config.display_name, 'display_name'); - assert.deepEqual(data.username, bceid_business_config.username, 'username'); - assert.deepEqual(data.email, bceid_business_config.email, 'email'); - assert.deepEqual(data.business_guid, bceid_business_config.guid, 'business guid'); - assert.deepEqual(data.business_legalname, bceid_business_config.legalname, 'business legalname'); - }); - - it('bceid-basic-business', async function () { - const data = await testsite( - fetchSsoUrl('BCEID_BOTH'), - bceid_business_config.username, - bceid_business_config.password, - 'BCEID_BASIC_BUSINESS', - page, - ); - assert.deepEqual(data.guid, bceid_business_config.user_identifier, 'user_identifier'); - assert.deepEqual(data.display_name, bceid_business_config.display_name, 'display_name'); - assert.deepEqual(data.username, bceid_business_config.username, 'username'); - assert.deepEqual(data.email, bceid_business_config.email, 'email'); - assert.equal(data.business_guid, bceid_business_config.guid, 'business guid'); - assert.deepEqual(data.business_legalname, bceid_business_config.legalname, 'business legalname'); - }); -}); diff --git a/siteminder-tests/util.js b/siteminder-tests/util.js deleted file mode 100644 index b5eb49e3..00000000 --- a/siteminder-tests/util.js +++ /dev/null @@ -1,89 +0,0 @@ -const { promisify } = require('util'); -const _ = require('lodash'); -const parseString = require('xml2js').parseString; -const fs = require('fs'); -const parseStringSync = promisify(parseString); -const Buffer = require('buffer').Buffer; -const screenShotsDir = './results/assets'; - -if (!fs.existsSync(screenShotsDir)) { - fs.mkdirSync(screenShotsDir, { recursive: true }); -} - -//take saml payload and put into a map -const parseFormData = (data) => { - const vars = data.split('&'); - const map = Object.create(null); - for (let i = 0; i < vars.length; i++) { - let pair = vars[i].split('='); - if (pair.length === 2) { - pair = pair.map(decodeURIComponent); - map[pair[0]] = pair[1]; - } - } - - return map; -}; - -const decodeBase64 = (data) => { - let buff = Buffer.from(data, 'base64'); - return buff.toString('ascii'); -}; - -module.exports = { - screenShotsDir, - testsite: async function (website, idp_username, idp_password, test_name, page) { - const siteminder_values = {}; - await page.waitForTimeout(1000); - await page.goto(website); - await page.waitForNavigation(); - await page.waitForSelector('title'); - await page.waitForSelector('input[name=user]'); - await page.type('#user', idp_username); - await page.type('#password', idp_password); - await page.keyboard.press('Enter'); - - const isIDIR = test_name.indexOf('IDIR') > -1; - - if (!isIDIR) { - await page.waitForTimeout(1000); - await page.waitForSelector('input[value=Continue]'); - await page.evaluate(() => { - const $button = document.querySelector('input[value=Continue]'); - $button.click(); - }); - } - - return new Promise((resolve) => { - page.on('request', async (request) => { - if (request.method() !== 'POST') return; - const data = request.postData(); - const entries = parseFormData(data); - - if (!entries.SAMLResponse) return; - - const cleanSamlResponse = entries.SAMLResponse.replace(/(\r\n|\n|\r)/gm, ''); - const decodedXML = decodeBase64(cleanSamlResponse); - const jsonResult = await parseStringSync(decodedXML); - const assertion = _.get(jsonResult, 'Response.ns2:Assertion.0'); - - const getAttribute = (data) => ({ [_.get(data, '$.Name')]: _.get(data, 'ns2:AttributeValue.0') }); - const statements = _.get(assertion, 'ns2:AttributeStatement.0.ns2:Attribute'); - - const attributes = _.reduce(statements, (ret, data) => ({ ...ret, ...getAttribute(data) }), {}); - - siteminder_values.guid = attributes['useridentifier'] ?? attributes['SMGOV_USERGUID'] ?? ''; - siteminder_values.username = attributes['username']; - siteminder_values.email = attributes['email']; - siteminder_values.display_name = - attributes['displayname'] ?? attributes['displayName'] ?? attributes['SMGOV_USERDISPLAYNAME'] ?? ''; - siteminder_values.firstname = attributes['firstname'] ?? ''; - siteminder_values.lastname = attributes['lastname'] ?? ''; - siteminder_values.business_guid = attributes['SMGOV_BUSINESSGUID'] ?? ''; - siteminder_values.business_legalname = attributes['SMGOV_BUSINESSLEGALNAME'] ?? ''; - - resolve(siteminder_values); - }); - }); - }, -}; From 44e252cd3e7f36d70765b49444a52e656bf020c4 Mon Sep 17 00:00:00 2001 From: Junmin Ahn Date: Wed, 26 Oct 2022 11:59:26 -0700 Subject: [PATCH 010/118] chore: add github payload comparison btw silver and gold --- docs/migration-guide.md | 48 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/docs/migration-guide.md b/docs/migration-guide.md index 02be6265..3d43ff9f 100644 --- a/docs/migration-guide.md +++ b/docs/migration-guide.md @@ -27,7 +27,7 @@ | IDIR User GUID | useridentifier | idir_user_guid | idir_user_guid | idir_user_guid | | | | preferred_username | preferred_username=`{{useridentifier}}@idir` | preferred_username=`{{useridentifier}}@idir` | -### BCeID Basic +### Basic BCeID - In Silver @@ -48,7 +48,7 @@ | BCeID User GUID | useridentifier | bceid_user_guid | bceid_user_guid | bceid_user_guid | | | | preferred_username | preferred_username=`{{useridentifier}}@bceidbasic` | preferred_username=`{{useridentifier}}@bceidbasic` | -### BCeID Business +### Business BCeID - In Silver @@ -68,7 +68,49 @@ | Email | email | email | email | email | | BCeID User Guid | SMGOV_USERGUID | bceid_user_guid | bceid_user_guid | bceid_user_guid | | | | preferred_username | preferred_username=`{{SMGOV_USERGUID}}@bceidbusiness` | preferred_username=`{{SMGOV_USERGUID}}@bceidbusiness` | - | BCeID User Name | SMGOV_USERDISPLAYNAME | bceid_user_name | bceid_user_name | bceid_user_name | + | BCeID User Name | SMGOV_USERDISPLAYNAME | display_name | display_name | display_name | | BCeID Business Guid | SMGOV_BUSINESSGUID | bceid_business_guid | bceid_business_guid | bceid_business_guid | | BCeID Business Name | SMGOV_BUSINESSLEGALNAME | bceid_business_name | bceid_business_name | bceid_business_name | | BCeID Business ID | username | bceid_username | bceid_username | bceid_username | + +### GitHub Public + +- In Silver + + | | IDP | Parent Realm | Custom Realm, Standard Realm | Standard Realm - OIDC Payload | + | --------------- | ------- | ------------------ | ------------------------------------- | ------------------------------------- | + | Email | email | email | email | email | + | First Name | name[0] | given_name | given_name | given_name | + | Last Name | name[1] | family_name | family_name | family_name | + | GitHub ID | id | github_id | github_id | github_id | + | GitHub Username | login | preferred_username | preferred_username=`{{login}}@github` | preferred_username=`{{login}}@github` | + +- In Gold + + | | IDP | Parent Realm | Custom Realm, Standard Realm | Standard Realm - OIDC Payload | + | ----------------------- | ------- | ------------------ | ---------------------------------------- | ---------------------------------------- | + | Email | email | email | email | email | + | First Name | name[0] | given_name | given_name | given_name | + | Last Name | name[1] | family_name | family_name | family_name | + | Full Name | name | display_name | display_name | display_name | + | GitHub ID | id | github_id | github_id | github_id | + | | | preferred_username | preferred_username=`{{id}}@githubpublic` | preferred_username=`{{id}}@githubpublic` | + | GitHub Username | login | github_username | github_username | github_username | + | BCGov Github Membership | | org_verified | org_verified | org_verified | + | BCGov Github Orgs | | orgs | orgs | orgs | + +### GitHub BCGov + +- In Gold + + | | IDP | Parent Realm | Custom Realm, Standard Realm | Standard Realm - OIDC Payload | + | ----------------------- | ------- | ------------------ | --------------------------------------- | --------------------------------------- | + | Email | email | email | email | email | + | First Name | name[0] | given_name | given_name | given_name | + | Last Name | name[1] | family_name | family_name | family_name | + | Full Name | name | display_name | display_name | display_name | + | GitHub ID | id | github_id | github_id | github_id | + | | | preferred_username | preferred_username=`{{id}}@githubbcgov` | preferred_username=`{{id}}@githubbcgov` | + | GitHub Username | login | github_username | github_username | github_username | + | BCGov Github Membership | | org_verified | org_verified | org_verified | + | BCGov Github Orgs | | orgs | orgs | orgs | From 119555d63ff931c32bd2c3b48b66d0b0e62b9f6d Mon Sep 17 00:00:00 2001 From: Junmin Ahn Date: Wed, 26 Oct 2022 12:05:06 -0700 Subject: [PATCH 011/118] chore: update migration mapper doc --- docs/migration-guide.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/migration-guide.md b/docs/migration-guide.md index 3d43ff9f..a3e41e69 100644 --- a/docs/migration-guide.md +++ b/docs/migration-guide.md @@ -114,3 +114,6 @@ | GitHub Username | login | github_username | github_username | github_username | | BCGov Github Membership | | org_verified | org_verified | org_verified | | BCGov Github Orgs | | orgs | orgs | orgs | + + - `org_verified`: `true` if the authenticated user has `bcgov` GitHub org membership, otherwise, `false`. + - `orgs`: `space-separated` list of BCGov GitHub org that the authenticated user has a membership of. From 5cd6f6723a8140295783ddfd38eb0eac331d2493 Mon Sep 17 00:00:00 2001 From: Junmin Ahn Date: Wed, 26 Oct 2022 12:16:25 -0700 Subject: [PATCH 012/118] chore: rename migration script folder --- scripts/{role-migrations => migrations}/groups-clientroles.js | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename scripts/{role-migrations => migrations}/groups-clientroles.js (100%) diff --git a/scripts/role-migrations/groups-clientroles.js b/scripts/migrations/groups-clientroles.js similarity index 100% rename from scripts/role-migrations/groups-clientroles.js rename to scripts/migrations/groups-clientroles.js From a3b26c12d5f8ddb1b19ca68ae1ac4fb0d43d69ac Mon Sep 17 00:00:00 2001 From: Jonathan Sharman Date: Wed, 26 Oct 2022 14:20:23 -0700 Subject: [PATCH 013/118] chore: fixRestore --- .../values-3d5c3f-dev-patroni-backup-storage.yaml | 9 ++++++++- .../values-6d70e7-dev-patroni-backup-storage.yaml | 7 ++++++- .../values-6d70e7-prod-patroni-backup-storage.yaml | 8 +++++++- .../values-6d70e7-test-patroni-backup-storage.yaml | 7 ++++++- 4 files changed, 27 insertions(+), 4 deletions(-) diff --git a/helm/backup-storage/values-3d5c3f-dev-patroni-backup-storage.yaml b/helm/backup-storage/values-3d5c3f-dev-patroni-backup-storage.yaml index 2243c6fd..1398e82f 100644 --- a/helm/backup-storage/values-3d5c3f-dev-patroni-backup-storage.yaml +++ b/helm/backup-storage/values-3d5c3f-dev-patroni-backup-storage.yaml @@ -1,11 +1,18 @@ nameOverride: "sso-backup-storage" fullnameOverride: "sso-backup-storage" +image: + repository: ghcr.io/bcgov/backup-storage + tag: postgres-13 + # repository: ghcr.io/bcgov/backup-storage + tag: latest + # pullPolicy: Always + backupConfig: | postgres=sso-pgsql-dev-11-patroni:5432/rhsso 0 1 * * * default ./backup.sh -s - 0 4 * * * default ./backup.sh -s -v all + # 0 4 * * * default ./backup.sh -s -v all db: secretName: sso-pgsql-dev diff --git a/helm/backup-storage/values-6d70e7-dev-patroni-backup-storage.yaml b/helm/backup-storage/values-6d70e7-dev-patroni-backup-storage.yaml index 74fc339e..2499872d 100644 --- a/helm/backup-storage/values-6d70e7-dev-patroni-backup-storage.yaml +++ b/helm/backup-storage/values-6d70e7-dev-patroni-backup-storage.yaml @@ -1,11 +1,16 @@ nameOverride: "sso-backup-storage" fullnameOverride: "sso-backup-storage" +image: + repository: ghcr.io/bcgov/backup-storage + tag: postgres-13 + pullPolicy: Always + backupConfig: | postgres=sso-pgsql-dev-11-patroni:5432/rhsso 0 1 * * * default ./backup.sh -s - 0 4 * * * default ./backup.sh -s -v all + # 0 4 * * * default ./backup.sh -s -v all db: secretName: patroni-11-dev-secret diff --git a/helm/backup-storage/values-6d70e7-prod-patroni-backup-storage.yaml b/helm/backup-storage/values-6d70e7-prod-patroni-backup-storage.yaml index 2bfc0146..af6e0889 100644 --- a/helm/backup-storage/values-6d70e7-prod-patroni-backup-storage.yaml +++ b/helm/backup-storage/values-6d70e7-prod-patroni-backup-storage.yaml @@ -1,11 +1,17 @@ nameOverride: "sso-backup-storage" fullnameOverride: "sso-backup-storage" +image: + repository: ghcr.io/bcgov/backup-storage + tag: postgres-13 + pullPolicy: Always + backupConfig: | postgres=sso-pgsql-prod-11-patroni:5432/rhsso 0 1 * * * default ./backup.sh -s - 0 4 * * * default ./backup.sh -s -v all + # 0 4 * * * default ./backup.sh -s -v all + db: secretName: patroni-11-prod-secret usernameKey: username diff --git a/helm/backup-storage/values-6d70e7-test-patroni-backup-storage.yaml b/helm/backup-storage/values-6d70e7-test-patroni-backup-storage.yaml index 37cb8f18..76550d65 100644 --- a/helm/backup-storage/values-6d70e7-test-patroni-backup-storage.yaml +++ b/helm/backup-storage/values-6d70e7-test-patroni-backup-storage.yaml @@ -1,11 +1,16 @@ nameOverride: "sso-backup-storage" fullnameOverride: "sso-backup-storage" +image: + repository: ghcr.io/bcgov/backup-storage + tag: postgres-13 + pullPolicy: Always + backupConfig: | postgres=sso-pgsql-test-11-patroni:5432/keycloak 0 1 * * * default ./backup.sh -s - 0 4 * * * default ./backup.sh -s -v all + # 0 4 * * * default ./backup.sh -s -v all db: secretName: patroni-11-test-secret From a58f34af268f6234ddfe4174b4b54ee60dad3639 Mon Sep 17 00:00:00 2001 From: Jonathan Sharman Date: Wed, 26 Oct 2022 14:31:01 -0700 Subject: [PATCH 014/118] chore: fixRestore add notes about verification step to readme --- helm/backup-storage/README.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/helm/backup-storage/README.md b/helm/backup-storage/README.md index 09236b9b..a618f5de 100644 --- a/helm/backup-storage/README.md +++ b/helm/backup-storage/README.md @@ -1,3 +1,20 @@ + +## **BEFORE RUNNING HELM UPGRADE:** + +Make sure to add the rocket chat webhook to production facing values files. Make sure not to commit this value. + +## Intro to backup container + +The current patroni clusters are backud up using a modified version of the platform services backup container. This is due to an issue with the spilo patroni image. + +The backup container repo is [here](https://github.com/BCDevOps/backup-container). + +The modified postgres plugin can be found [here](https://github.com/bcgov/sso-keycloak/blob/dev/docker/backup-container/backup.postgres.plugin). + +A side effect of this conflict is that we cannot currently verify the daily backups with a test restoration. + +## Installing and upgrading backups + These charts can be upgraded using make commands: `make upgrade NAME=patroni-backup-storage NAMESPACE=<>` @@ -15,3 +32,6 @@ To restore from the most recent backup, rsh into the backup pod in the namespace **prod silver production**: `./backup.sh -r postgres=sso-pgsql-prod-11-patroni:5432/rhsso` + + +`./backup.sh -r postgres=sso-pgsql-dev-11-patroni:5432/keycloak -f backups/ ` From 1a68b4ad2f87b6ac05bdab98fcf52de4fa58b283 Mon Sep 17 00:00:00 2001 From: Jonathan Sharman Date: Wed, 26 Oct 2022 14:32:56 -0700 Subject: [PATCH 015/118] chore: fixRestore add notes about verification step to readme --- helm/backup-storage/README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/helm/backup-storage/README.md b/helm/backup-storage/README.md index a618f5de..09da175e 100644 --- a/helm/backup-storage/README.md +++ b/helm/backup-storage/README.md @@ -32,6 +32,3 @@ To restore from the most recent backup, rsh into the backup pod in the namespace **prod silver production**: `./backup.sh -r postgres=sso-pgsql-prod-11-patroni:5432/rhsso` - - -`./backup.sh -r postgres=sso-pgsql-dev-11-patroni:5432/keycloak -f backups/ ` From cbfebefcef5e64b1662d22a88abde7ef5934cb25 Mon Sep 17 00:00:00 2001 From: Jonathan Sharman Date: Wed, 26 Oct 2022 14:34:13 -0700 Subject: [PATCH 016/118] chore: fixRestore add notes about verification step to readme --- .../values-3d5c3f-dev-patroni-backup-storage.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/helm/backup-storage/values-3d5c3f-dev-patroni-backup-storage.yaml b/helm/backup-storage/values-3d5c3f-dev-patroni-backup-storage.yaml index 1398e82f..48ad27b3 100644 --- a/helm/backup-storage/values-3d5c3f-dev-patroni-backup-storage.yaml +++ b/helm/backup-storage/values-3d5c3f-dev-patroni-backup-storage.yaml @@ -5,8 +5,8 @@ image: repository: ghcr.io/bcgov/backup-storage tag: postgres-13 # repository: ghcr.io/bcgov/backup-storage - tag: latest - # pullPolicy: Always + # tag: latest + pullPolicy: Always backupConfig: | postgres=sso-pgsql-dev-11-patroni:5432/rhsso From bd8be40bc5bbfb84a2c7e95ee005bb8917e6fcdf Mon Sep 17 00:00:00 2001 From: Jonathan Sharman Date: Wed, 26 Oct 2022 14:35:37 -0700 Subject: [PATCH 017/118] chore: fixRestore --- .../values-3d5c3f-dev-patroni-backup-storage.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/helm/backup-storage/values-3d5c3f-dev-patroni-backup-storage.yaml b/helm/backup-storage/values-3d5c3f-dev-patroni-backup-storage.yaml index 48ad27b3..d14eb76e 100644 --- a/helm/backup-storage/values-3d5c3f-dev-patroni-backup-storage.yaml +++ b/helm/backup-storage/values-3d5c3f-dev-patroni-backup-storage.yaml @@ -4,9 +4,10 @@ fullnameOverride: "sso-backup-storage" image: repository: ghcr.io/bcgov/backup-storage tag: postgres-13 - # repository: ghcr.io/bcgov/backup-storage - # tag: latest pullPolicy: Always + # # The bcgov repos version for testing + # repository: bcgovimages/backup-container + # tag: v7.6.5-build.13 backupConfig: | postgres=sso-pgsql-dev-11-patroni:5432/rhsso From fbf7450413969d348ae339ef3fbf3071e35f5161 Mon Sep 17 00:00:00 2001 From: Junmin Ahn Date: Thu, 27 Oct 2022 15:24:49 -0700 Subject: [PATCH 018/118] chore: update github attribute documentation --- docs/migration-guide.md | 42 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/docs/migration-guide.md b/docs/migration-guide.md index a3e41e69..321aa751 100644 --- a/docs/migration-guide.md +++ b/docs/migration-guide.md @@ -87,33 +87,31 @@ - In Gold - | | IDP | Parent Realm | Custom Realm, Standard Realm | Standard Realm - OIDC Payload | - | ----------------------- | ------- | ------------------ | ---------------------------------------- | ---------------------------------------- | - | Email | email | email | email | email | - | First Name | name[0] | given_name | given_name | given_name | - | Last Name | name[1] | family_name | family_name | family_name | - | Full Name | name | display_name | display_name | display_name | - | GitHub ID | id | github_id | github_id | github_id | - | | | preferred_username | preferred_username=`{{id}}@githubpublic` | preferred_username=`{{id}}@githubpublic` | - | GitHub Username | login | github_username | github_username | github_username | - | BCGov Github Membership | | org_verified | org_verified | org_verified | - | BCGov Github Orgs | | orgs | orgs | orgs | + | | IDP | Parent Realm | Custom Realm, Standard Realm | Standard Realm - OIDC Payload | + | ----------------------- | ----- | ------------------ | ---------------------------------------- | ---------------------------------------- | + | Email | email | email | email | email | + | Full Name | name | display_name | display_name | display_name | + | | | | | name | + | GitHub ID | id | github_id | github_id | github_id | + | | | preferred_username | preferred_username=`{{id}}@githubpublic` | preferred_username=`{{id}}@githubpublic` | + | GitHub Username | login | github_username | github_username | github_username | + | BCGov Github Membership | | org_verified | org_verified | org_verified | + | BCGov Github Orgs | | orgs | orgs | orgs | ### GitHub BCGov - In Gold - | | IDP | Parent Realm | Custom Realm, Standard Realm | Standard Realm - OIDC Payload | - | ----------------------- | ------- | ------------------ | --------------------------------------- | --------------------------------------- | - | Email | email | email | email | email | - | First Name | name[0] | given_name | given_name | given_name | - | Last Name | name[1] | family_name | family_name | family_name | - | Full Name | name | display_name | display_name | display_name | - | GitHub ID | id | github_id | github_id | github_id | - | | | preferred_username | preferred_username=`{{id}}@githubbcgov` | preferred_username=`{{id}}@githubbcgov` | - | GitHub Username | login | github_username | github_username | github_username | - | BCGov Github Membership | | org_verified | org_verified | org_verified | - | BCGov Github Orgs | | orgs | orgs | orgs | + | | IDP | Parent Realm | Custom Realm, Standard Realm | Standard Realm - OIDC Payload | + | ----------------------- | ----- | ------------------ | --------------------------------------- | --------------------------------------- | + | Email | email | email | email | email | + | Full Name | name | display_name | display_name | display_name | + | | | | | name | + | GitHub ID | id | github_id | github_id | github_id | + | | | preferred_username | preferred_username=`{{id}}@githubbcgov` | preferred_username=`{{id}}@githubbcgov` | + | GitHub Username | login | github_username | github_username | github_username | + | BCGov Github Membership | | org_verified | org_verified | org_verified | + | BCGov Github Orgs | | orgs | orgs | orgs | - `org_verified`: `true` if the authenticated user has `bcgov` GitHub org membership, otherwise, `false`. - `orgs`: `space-separated` list of BCGov GitHub org that the authenticated user has a membership of. From 7905ba06ae890c80137880825efaf6c62a6c4a99 Mon Sep 17 00:00:00 2001 From: Junmin Ahn Date: Fri, 28 Oct 2022 13:06:23 -0700 Subject: [PATCH 019/118] feat: add migration script for mds --- scripts/migrations/groups-clientroles.js | 2 +- .../helpers/migrate-target-idir-users.js | 83 ++++++ scripts/migrations/mds.js | 256 ++++++++++++++++++ 3 files changed, 340 insertions(+), 1 deletion(-) create mode 100644 scripts/migrations/helpers/migrate-target-idir-users.js create mode 100644 scripts/migrations/mds.js diff --git a/scripts/migrations/groups-clientroles.js b/scripts/migrations/groups-clientroles.js index dcaef1cb..312fcd79 100644 --- a/scripts/migrations/groups-clientroles.js +++ b/scripts/migrations/groups-clientroles.js @@ -10,7 +10,7 @@ async function main() { if (!baseEnv || !baseRealm || !targetEnv || !targetClient) { console.info(` Usages: - node role-migrations/groups-clientroles.js --base-env --base-realm --target-env --target-client [--target-realm ] [--auto] + node migrations/groups-clientroles --base-env --base-realm --target-env --target-client [--target-realm ] [--auto] `); return; diff --git a/scripts/migrations/helpers/migrate-target-idir-users.js b/scripts/migrations/helpers/migrate-target-idir-users.js new file mode 100644 index 00000000..c94c7600 --- /dev/null +++ b/scripts/migrations/helpers/migrate-target-idir-users.js @@ -0,0 +1,83 @@ +const _ = require('lodash'); +const { handleError, ignoreError } = require('../../helpers'); + +const logPrefix = 'MIGRATE SILVER IDIR TO GOLD STANDARD: '; + +const migrateSilverIdirToGoldStandard = async (baseAdminClient, targetAdminClient, idirUsernames) => { + if (!baseAdminClient || !targetAdminClient) return; + + for (let x = 0; x < idirUsernames.length; x++) { + const username = idirUsernames[x]; + + try { + const baseIdirUsers = await baseAdminClient.users.find({ realm: 'idir', username, max: 1 }); + if (baseIdirUsers.length === 0) { + console.log(`${logPrefix}not found ${username}`); + continue; + } + + const baseIdirUser = baseIdirUsers[0]; + if (!baseIdirUser.attributes.idir_userid) { + console.log(`${logPrefix}no user guid ${username}`); + continue; + } + + const baseIdirGuid = baseIdirUser.attributes.idir_userid[0]; + + const commonUserData = { + enabled: true, + email: baseIdirUser.email, + firstName: baseIdirUser.firstName, + lastName: baseIdirUser.lastName, + attributes: { + display_name: (baseIdirUser.attributes.displayName && baseIdirUser.attributes.displayName[0]) || '', + idir_user_guid: baseIdirGuid, + idir_username: username, + }, + }; + + let targetIdirUser = await targetAdminClient.users.create({ + ...commonUserData, + realm: 'idir', + username: baseIdirGuid, + }); + + targetIdirUser = await targetAdminClient.users.findOne({ realm: 'idir', id: targetIdirUser.id }); + + await targetAdminClient.users.addToFederatedIdentity({ + realm: 'idir', + id: targetIdirUser.id, + federatedIdentityId: 'idir', + federatedIdentity: { + userId: baseIdirGuid, + userName: baseIdirGuid, + identityProvider: 'idir', + }, + }); + + const targetStandardUser = await targetAdminClient.users.create({ + ...commonUserData, + realm: 'standard', + username: `${baseIdirGuid}@idir`, + }); + + await targetAdminClient.users.addToFederatedIdentity({ + realm: 'standard', + id: targetStandardUser.id, + federatedIdentityId: 'idir', + federatedIdentity: { + userId: targetIdirUser.id, + userName: targetIdirUser.username, + identityProvider: 'idir', + }, + }); + + console.error(`${logPrefix}${username} created`); + } catch (err) { + console.error(`${logPrefix}error with: ${username}`); + handleError(err); + } + } +}; + +module.exports = { migrateSilverIdirToGoldStandard }; diff --git a/scripts/migrations/mds.js b/scripts/migrations/mds.js new file mode 100644 index 00000000..6ae83885 --- /dev/null +++ b/scripts/migrations/mds.js @@ -0,0 +1,256 @@ +const fs = require('fs'); +const path = require('path'); +const _ = require('lodash'); +const { argv } = require('yargs'); +const Confirm = require('prompt-confirm'); +const { getAdminClient } = require('../keycloak-core'); +const { handleError, ignoreError } = require('../helpers'); +const { migrateSilverIdirToGoldStandard } = require('./helpers/migrate-target-idir-users'); +const { baseEnv, baseRealm, targetEnv, targetRealm = 'standard', targetClient, auto } = argv; + +const rolesToExclude = ['uma_authorization', 'offline_access']; +const idpToRealmMap = { + idir: 'idir', + bceid: '_bceid', +}; + +const idpToGuidKeyMap = { + idir: 'idir_userid', + bceid: 'bceid_userid', +}; + +const suffixMap = { + idir: 'idir', + bceid: 'bceidboth', +}; + +async function main() { + if (!baseEnv || !baseRealm || !targetEnv || !targetClient) { + console.info(` + Usages: + node migrations/mds --base-env --base-realm --target-env --target-client [--target-realm ] [--auto] + `); + + return; + } + + try { + const baseAdminClient = await getAdminClient(baseEnv, { totp: '657347' }); + const targetAdminClient = await getAdminClient(targetEnv); + if (!baseAdminClient || !targetAdminClient) return; + + if (!auto) { + const prompt = new Confirm(`Are you sure to proceed?`); + const answer = await prompt.run(); + if (!answer) return; + } + + // see if the target client exists first + const clients = await targetAdminClient.clients.find({ realm: targetRealm, clientId: targetClient, max: 1 }); + if (clients.length === 0) throw Error('client not found'); + + const clientId = clients[0].id; + + console.log('Step 1: build the role associations'); + const baseGroups = await baseAdminClient.groups.find({ realm: baseRealm }); + const baseRoles = await baseAdminClient.roles.find({ realm: baseRealm }); + + const masterRoleMappings = []; + + for (let x = 0; x < baseGroups.length; x++) { + const group = baseGroups[x]; + + const roleMappings = await baseAdminClient.groups.listRealmRoleMappings({ + realm: baseRealm, + id: group.id, + }); + + masterRoleMappings.push({ + type: 'group', + id: group.id, + name: group.name, + children: roleMappings.map((mapping) => mapping.name), + }); + } + + for (let x = 0; x < baseRoles.length; x++) { + const role = baseRoles[x]; + if (rolesToExclude.includes(role.name)) continue; + + let roleMappings = await baseAdminClient.roles.getCompositeRolesForRealm({ realm: baseRealm, id: role.id }); + roleMappings = roleMappings.filter((mapping) => !rolesToExclude.includes(mapping.name)); + + masterRoleMappings.push({ + type: 'role', + id: role.id, + name: role.name, + children: roleMappings.map((mapping) => mapping.name), + }); + } + + console.log('Step 2: collect the base user & role mappings'); + const baseUserMap = {}; + + for (let x = 0; x < masterRoleMappings.length; x++) { + const roleMapping = masterRoleMappings[x]; + + const users = + roleMapping.type === 'group' + ? await baseAdminClient.groups.listMembers({ realm: baseRealm, id: roleMapping.id }) + : await baseAdminClient.roles.findUsersWithRole({ realm: baseRealm, name: roleMapping.name }); + + // masterRoleMappings.push({ name: role.name, children: roleMappings.map((mapping) => mapping.name) }); + users.forEach((user) => { + if (!baseUserMap[user.id]) baseUserMap[user.id] = { ...user, roles: [] }; + baseUserMap[user.id].roles.push(roleMapping.name); + }); + } + + const allBaseUsers = Object.values(baseUserMap); + + console.log('Step 3: find the matching Gold standard users'); + const idpMap = {}; + + const userReport = { + found: [], + 'no-idp': [], + 'no-guid': [], + }; + + const validUserMeta = []; + + for (let x = 0; x < allBaseUsers.length; x++) { + const buser = allBaseUsers[x]; + const links = await baseAdminClient.users.listFederatedIdentities({ + realm: baseRealm, + id: buser.id, + }); + + if (links.length === 0) { + userReport['no-idp'].push(buser.username); + continue; + } + + const { identityProvider, userId } = links[0]; + const parentRealmName = idpToRealmMap[identityProvider]; + if (!parentRealmName) continue; + + const parentUser = await baseAdminClient.users.findOne({ realm: parentRealmName, id: userId }); + const buserGuid = _.get(parentUser, `attributes.${idpToGuidKeyMap[identityProvider]}.0`); + + if (!buserGuid) { + userReport['no-guid'].push(buser.username); + continue; + } + + if (!idpMap[identityProvider]) idpMap[identityProvider] = 0; + idpMap[identityProvider]++; + + let tusers = await targetAdminClient.users.find({ + realm: 'standard', + username: `${buserGuid}@${suffixMap[identityProvider]}`, + exact: true, + }); + + if (tusers.length === 0) { + const key = `not-found-${identityProvider}`; + if (!userReport[key]) userReport[key] = []; + userReport[key].push(buser.username); + } else { + userReport['found'].push(buser.username); + validUserMeta.push({ baseUserId: buser.id, targetUserId: tusers[0].id }); + } + } + + console.log('Step 4: migrate missing IDIR users'); + if (userReport['not-found-idir']) + await migrateSilverIdirToGoldStandard(baseAdminClient, targetAdminClient, userReport['not-found-idir']); + + const targetRoleMap = {}; + console.log('Step 5: create client level roles in the target realm'); + for (let x = 0; x < masterRoleMappings.length; x++) { + const roleMapping = masterRoleMappings[x]; + + let role = await targetAdminClient.clients.findRole({ + realm: targetRealm, + id: clientId, + roleName: roleMapping.name, + }); + + if (!role) { + role = await targetAdminClient.clients.createRole({ + id: clientId, + realm: targetRealm, + name: roleMapping.name, + composite: roleMapping.children.length > 0, + clientRole: true, + containerId: clientId, + }); + + role = await targetAdminClient.clients.findRole({ + realm: targetRealm, + id: clientId, + roleName: roleMapping.name, + }); + } + + targetRoleMap[roleMapping.name] = role; + } + + console.log('Step 6: create composite role mappings in the target realm'); + for (let x = 0; x < masterRoleMappings.length; x++) { + const roleMapping = masterRoleMappings[x]; + + const role = await targetAdminClient.clients.findRole({ + realm: targetRealm, + id: clientId, + roleName: roleMapping.name, + }); + + const rolesToDel = await targetAdminClient.roles.getCompositeRolesForClient({ + realm: targetRealm, + clientId: clientId, + id: role.id, + }); + + const rolesToAdd = await Promise.all( + roleMapping.children.map((roleName) => + targetAdminClient.clients.findRole({ + realm: targetRealm, + id: clientId, + roleName, + }), + ), + ); + + // remove existing ones first before adding composite roles + await targetAdminClient.roles.delCompositeRoles({ realm: targetRealm, id: role.id }, rolesToDel); + await targetAdminClient.roles.createComposite({ realm: targetRealm, roleId: role.id }, rolesToAdd); + } + + console.log('Step 7: create user role mappings in the target realm'); + for (let x = 0; x < validUserMeta.length; x++) { + const meta = validUserMeta[x]; + + const roleMapping = { + realm: targetRealm, + id: meta.targetUserId, + clientUniqueId: clientId, + }; + + const roleNames = baseUserMap[meta.baseUserId].roles; + const roles = roleNames.map((roleName) => _.pick(targetRoleMap[roleName], ['id', 'name'])); + const roleMappingUpdate = { ...roleMapping, roles }; + await targetAdminClient.users.addClientRoleMappings(roleMappingUpdate); + } + + fs.writeFileSync(path.resolve(__dirname, 'mds.json'), JSON.stringify({ masterRoleMappings, userReport }, null, 2)); + + process.exit(0); + } catch (err) { + handleError(err); + process.exit(1); + } +} + +main(); From e0024acc7df81e96f757d6a56475e28029af8aaa Mon Sep 17 00:00:00 2001 From: Junmin Ahn Date: Mon, 31 Oct 2022 11:59:52 -0700 Subject: [PATCH 020/118] chore: resolve repo-mountie issues --- COMPLIANCE.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 COMPLIANCE.yaml diff --git a/COMPLIANCE.yaml b/COMPLIANCE.yaml new file mode 100644 index 00000000..9db625c7 --- /dev/null +++ b/COMPLIANCE.yaml @@ -0,0 +1,10 @@ +name: compliance +description: | + This repository does not contain any production application codebase. When this changes we will update this file. +spec: +- name: PIA + status: not-required + last-updated: '2022-10-31' +- name: STRA + status: not-required + last-updated: '2022-10-31' From a3a4354fd8491879812ef9643e26febef395307f Mon Sep 17 00:00:00 2001 From: Junmin Ahn Date: Mon, 31 Oct 2022 16:26:35 -0700 Subject: [PATCH 021/118] feat: update cookie authenticator to respect kc_idp_hint for sso --- .../CookieStopAuthenticator.java | 80 +++++++++++++------ 1 file changed, 57 insertions(+), 23 deletions(-) diff --git a/docker/keycloak/extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/authenticators/CookieStopAuthenticator.java b/docker/keycloak/extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/authenticators/CookieStopAuthenticator.java index 960043ca..02713ce8 100755 --- a/docker/keycloak/extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/authenticators/CookieStopAuthenticator.java +++ b/docker/keycloak/extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/authenticators/CookieStopAuthenticator.java @@ -1,12 +1,19 @@ package com.github.bcgov.keycloak.authenticators; +import java.util.Map; +import javax.ws.rs.core.MultivaluedMap; +import java.util.ArrayList; import org.jboss.logging.Logger; import org.keycloak.authentication.AuthenticationFlowContext; import org.keycloak.authentication.Authenticator; +import org.keycloak.constants.AdapterConstants; import org.keycloak.models.AuthenticatedClientSessionModel; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; +import org.keycloak.models.IdentityProviderModel; import org.keycloak.models.UserModel; +import org.keycloak.models.UserSessionProvider; +import org.keycloak.models.ClientScopeModel; import org.keycloak.protocol.LoginProtocol; import org.keycloak.services.managers.AuthenticationManager; import org.keycloak.sessions.AuthenticationSessionModel; @@ -26,35 +33,62 @@ public void authenticate(AuthenticationFlowContext context) { AuthenticationManager.AuthResult authResult = AuthenticationManager.authenticateIdentityCookie( context.getSession(), context.getRealm(), true); + + // 1. If no Cookie session, proceed to login process if (authResult == null) { context.attempted(); - } else { - AuthenticationSessionModel clientSession = context.getAuthenticationSession(); - LoginProtocol protocol = - context.getSession().getProvider(LoginProtocol.class, clientSession.getProtocol()); + return; + } + + AuthenticationSessionModel authSession = context.getAuthenticationSession(); + LoginProtocol protocol = + context.getSession().getProvider(LoginProtocol.class, authSession.getProtocol()); + context.setUser(authResult.getUser()); + + // 2. if re-authentication is required, proceed to login process + if (protocol.requireReauthentication(authResult.getSession(), authSession)) { + context.attempted(); + return; + } + + String clientUUID = authSession.getClient().getId(); + AuthenticatedClientSessionModel clientSessionModel = + authResult.getSession().getAuthenticatedClientSessionByClient(clientUUID); + UserSessionProvider userSessionProvider = context.getSession().sessions(); + + // 3. If no Cookie session with the authenticating client, proceed to login process + if (clientSessionModel == null) { + context.attempted(); + return; + } + + MultivaluedMap queryParams = context.getUriInfo().getQueryParameters(); - // Cookie re-authentication is skipped if re-authentication is required - if (protocol.requireReauthentication(authResult.getSession(), clientSession)) { + // 4. If a target IDP is passed via "kc_idp_hint" query param, and + // i. the target IDP is enabled; + // ii. the target IDP is allowed for the authenticating client; + // iii. the target IDP is different one than the one in the user session; + // then, logout the user from the current session and proceed to login process + if (queryParams.containsKey(AdapterConstants.KC_IDP_HINT)) { + String authIdp = queryParams.getFirst(AdapterConstants.KC_IDP_HINT); + String sessIdp = authResult.getSession().getNotes().get("identity_provider"); + + IdentityProviderModel idp = context.getRealm().getIdentityProviderByAlias(authIdp); + Map scopes = + context.getAuthenticationSession().getClient().getClientScopes(true); + + if (idp.isEnabled() && (scopes.containsKey(authIdp) || scopes.containsKey(authIdp + "-saml")) && authIdp != sessIdp) { + userSessionProvider.removeUserSession(context.getRealm(), authResult.getSession()); context.attempted(); - } else { - String clientUUID = clientSession.getClient().getId(); - AuthenticatedClientSessionModel clientSessionModel = - authResult.getSession().getAuthenticatedClientSessionByClient(clientUUID); - - // If the user does not have a client-level sessions in the browser cookie, then force to - // re-authenticate - if (clientSessionModel == null) { - context.attempted(); - return; - } - - // Otherwise, grant the exisiting session to the user - context.getAuthenticationSession().setAuthNote(AuthenticationManager.SSO_AUTH, "true"); - context.setUser(authResult.getUser()); - context.attachUserSession(authResult.getSession()); - context.success(); + return; } } + + // 5. Otherwise, attach the exisiting session to the user + context.getAuthenticationSession().setAuthNote(AuthenticationManager.SSO_AUTH, "true"); + context.setUser(authResult.getUser()); + context.attachUserSession(authResult.getSession()); + context.success(); } @Override From d6f141d1bdfccebecec085111744ac9cbb30cd7d Mon Sep 17 00:00:00 2001 From: Junmin Ahn Date: Tue, 1 Nov 2022 09:00:05 -0700 Subject: [PATCH 022/118] chore: reorder cookie authenticator logic --- .../CookieStopAuthenticator.java | 33 ++++++++++--------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/docker/keycloak/extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/authenticators/CookieStopAuthenticator.java b/docker/keycloak/extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/authenticators/CookieStopAuthenticator.java index 02713ce8..f1393ee7 100755 --- a/docker/keycloak/extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/authenticators/CookieStopAuthenticator.java +++ b/docker/keycloak/extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/authenticators/CookieStopAuthenticator.java @@ -2,18 +2,17 @@ import java.util.Map; import javax.ws.rs.core.MultivaluedMap; -import java.util.ArrayList; import org.jboss.logging.Logger; import org.keycloak.authentication.AuthenticationFlowContext; import org.keycloak.authentication.Authenticator; import org.keycloak.constants.AdapterConstants; import org.keycloak.models.AuthenticatedClientSessionModel; +import org.keycloak.models.ClientScopeModel; +import org.keycloak.models.IdentityProviderModel; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; -import org.keycloak.models.IdentityProviderModel; import org.keycloak.models.UserModel; import org.keycloak.models.UserSessionProvider; -import org.keycloak.models.ClientScopeModel; import org.keycloak.protocol.LoginProtocol; import org.keycloak.services.managers.AuthenticationManager; import org.keycloak.sessions.AuthenticationSessionModel; @@ -51,20 +50,9 @@ public void authenticate(AuthenticationFlowContext context) { return; } - String clientUUID = authSession.getClient().getId(); - AuthenticatedClientSessionModel clientSessionModel = - authResult.getSession().getAuthenticatedClientSessionByClient(clientUUID); - UserSessionProvider userSessionProvider = context.getSession().sessions(); - - // 3. If no Cookie session with the authenticating client, proceed to login process - if (clientSessionModel == null) { - context.attempted(); - return; - } - MultivaluedMap queryParams = context.getUriInfo().getQueryParameters(); - // 4. If a target IDP is passed via "kc_idp_hint" query param, and + // 3. If a target IDP is passed via "kc_idp_hint" query param, and // i. the target IDP is enabled; // ii. the target IDP is allowed for the authenticating client; // iii. the target IDP is different one than the one in the user session; @@ -77,13 +65,26 @@ public void authenticate(AuthenticationFlowContext context) { Map scopes = context.getAuthenticationSession().getClient().getClientScopes(true); - if (idp.isEnabled() && (scopes.containsKey(authIdp) || scopes.containsKey(authIdp + "-saml")) && authIdp != sessIdp) { + if (idp.isEnabled() + && (scopes.containsKey(authIdp) || scopes.containsKey(authIdp + "-saml")) + && authIdp != sessIdp) { + UserSessionProvider userSessionProvider = context.getSession().sessions(); userSessionProvider.removeUserSession(context.getRealm(), authResult.getSession()); context.attempted(); return; } } + String clientUUID = authSession.getClient().getId(); + AuthenticatedClientSessionModel clientSessionModel = + authResult.getSession().getAuthenticatedClientSessionByClient(clientUUID); + + // 4. If no Cookie session with the authenticating client, proceed to login process + if (clientSessionModel == null) { + context.attempted(); + return; + } + // 5. Otherwise, attach the exisiting session to the user context.getAuthenticationSession().setAuthNote(AuthenticationManager.SSO_AUTH, "true"); context.setUser(authResult.getUser()); From f7446e4ed511f939554bc8b1c52d9a5f5235bd3f Mon Sep 17 00:00:00 2001 From: Junmin Ahn Date: Tue, 1 Nov 2022 16:33:19 -0700 Subject: [PATCH 023/118] chore: handle invalid kc_idp_hint --- .../CookieStopAuthenticator.java | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/docker/keycloak/extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/authenticators/CookieStopAuthenticator.java b/docker/keycloak/extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/authenticators/CookieStopAuthenticator.java index f1393ee7..39847fbe 100755 --- a/docker/keycloak/extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/authenticators/CookieStopAuthenticator.java +++ b/docker/keycloak/extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/authenticators/CookieStopAuthenticator.java @@ -61,17 +61,20 @@ public void authenticate(AuthenticationFlowContext context) { String authIdp = queryParams.getFirst(AdapterConstants.KC_IDP_HINT); String sessIdp = authResult.getSession().getNotes().get("identity_provider"); - IdentityProviderModel idp = context.getRealm().getIdentityProviderByAlias(authIdp); - Map scopes = - context.getAuthenticationSession().getClient().getClientScopes(true); - - if (idp.isEnabled() - && (scopes.containsKey(authIdp) || scopes.containsKey(authIdp + "-saml")) - && authIdp != sessIdp) { - UserSessionProvider userSessionProvider = context.getSession().sessions(); - userSessionProvider.removeUserSession(context.getRealm(), authResult.getSession()); - context.attempted(); - return; + if (authIdp != null && !authIdp.trim().isEmpty()) { + IdentityProviderModel idp = context.getRealm().getIdentityProviderByAlias(authIdp); + Map scopes = + context.getAuthenticationSession().getClient().getClientScopes(true); + + if (idp != null + && idp.isEnabled() + && (scopes.containsKey(authIdp) || scopes.containsKey(authIdp + "-saml")) + && authIdp != sessIdp) { + UserSessionProvider userSessionProvider = context.getSession().sessions(); + userSessionProvider.removeUserSession(context.getRealm(), authResult.getSession()); + context.attempted(); + return; + } } } From 08952ccbd15fd3420b306b5a55295375e97f2368 Mon Sep 17 00:00:00 2001 From: Junmin Ahn Date: Wed, 2 Nov 2022 15:59:44 -0700 Subject: [PATCH 024/118] chore: bump keycloak image version for sandbox instances --- helm/keycloak/values-b861c7-test-4.yaml | 2 +- helm/keycloak/values-b861c7-test-5.yaml | 2 +- helm/keycloak/values-b861c7-test-6.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/helm/keycloak/values-b861c7-test-4.yaml b/helm/keycloak/values-b861c7-test-4.yaml index 6ae43427..95c143f2 100644 --- a/helm/keycloak/values-b861c7-test-4.yaml +++ b/helm/keycloak/values-b861c7-test-4.yaml @@ -2,7 +2,7 @@ replicaCount: 1 image: repository: ghcr.io/bcgov/sso - tag: 7.6.5-build.12 + tag: 7.6.5-build.15 pullPolicy: IfNotPresent rollingUpdate: diff --git a/helm/keycloak/values-b861c7-test-5.yaml b/helm/keycloak/values-b861c7-test-5.yaml index 4de858b6..5c27b4ab 100644 --- a/helm/keycloak/values-b861c7-test-5.yaml +++ b/helm/keycloak/values-b861c7-test-5.yaml @@ -2,7 +2,7 @@ replicaCount: 1 image: repository: ghcr.io/bcgov/sso - tag: 7.6.5-build.12 + tag: 7.6.5-build.15 pullPolicy: IfNotPresent rollingUpdate: diff --git a/helm/keycloak/values-b861c7-test-6.yaml b/helm/keycloak/values-b861c7-test-6.yaml index 861dec40..ea315386 100644 --- a/helm/keycloak/values-b861c7-test-6.yaml +++ b/helm/keycloak/values-b861c7-test-6.yaml @@ -2,7 +2,7 @@ replicaCount: 1 image: repository: ghcr.io/bcgov/sso - tag: 7.6.5-build.12 + tag: 7.6.5-build.15 pullPolicy: IfNotPresent rollingUpdate: From b64d4dcd5ebf33bdf5924f74dd6d7f48cfe03962 Mon Sep 17 00:00:00 2001 From: Junmin Ahn Date: Thu, 3 Nov 2022 12:29:59 -0700 Subject: [PATCH 025/118] chore: update mds migration script to include bceid users --- scripts/.env.example | 7 + .../helpers/migrate-target-bceidboth-users.js | 182 ++++++++++++++++++ scripts/migrations/mds.js | 138 ++++++++----- scripts/package.json | 2 + scripts/yarn.lock | 82 ++++++++ 5 files changed, 358 insertions(+), 53 deletions(-) create mode 100644 scripts/migrations/helpers/migrate-target-bceidboth-users.js diff --git a/scripts/.env.example b/scripts/.env.example index e79d77d8..63e84794 100644 --- a/scripts/.env.example +++ b/scripts/.env.example @@ -33,3 +33,10 @@ GAMMA_KEYCLOAK_CLIENT_SECRET= GAMMA_KEYCLOAK_URL= GAMMA_KEYCLOAK_USERNAME= GAMMA_KEYCLOAK_PASSWORD= + +BCEID_SERVICE_BASIC_AUTH= +BCEID_REQUESTER_IDIR_GUID= + +BCEID_SERVICE_ID_DEV= +BCEID_SERVICE_ID_TEST= +BCEID_SERVICE_ID_PROD= diff --git a/scripts/migrations/helpers/migrate-target-bceidboth-users.js b/scripts/migrations/helpers/migrate-target-bceidboth-users.js new file mode 100644 index 00000000..cd46ce54 --- /dev/null +++ b/scripts/migrations/helpers/migrate-target-bceidboth-users.js @@ -0,0 +1,182 @@ +const { promisify } = require('util'); +const _ = require('lodash'); +const soapRequest = require('easy-soap-request'); +const { parseString } = require('xml2js'); +const { handleError, ignoreError } = require('../../helpers'); +const dotenv = require('dotenv'); +dotenv.config('../../'); + +const parseStringSync = promisify(parseString); +const logPrefix = 'BCEID BOTH: '; +const log = (msg) => console.log(`${logPrefix}${msg}`); + +const defaultHeaders = { + 'Content-Type': 'text/xml;charset=UTF-8', + authorization: `Basic ${process.env.BCEID_SERVICE_BASIC_AUTH}`, +}; + +const generateXML = ({ + property = 'userGuid', + accountType = 'Business', + matchKey = '', + serviceId = '', + idirUserGuid = process.env.BCEID_REQUESTER_IDIR_GUID, +}) => ` + + + + + + ${serviceId} + Internal + ${idirUserGuid} + <${property}>${matchKey} + ${accountType} + + + +`; + +const parseAccount = (data) => { + const guid = _.get(data, 'guid.0.value.0'); + const userId = _.get(data, 'userId.0.value.0'); + const displayName = _.get(data, 'displayName.0.value.0'); + const type = _.get(data, 'type.0.code.0'); + + return { guid, userId, displayName, type }; +}; + +const fetchBceidUser = async ({ accountType = 'Business', matchKey = '', env = 'dev' }) => { + let serviceUrl = ''; + let serviceId = ''; + if (env === 'dev') { + serviceUrl = 'https://gws2.development.bceid.ca'; + serviceId = process.env.BCEID_SERVICE_ID_DEV; + } else if (env === 'test') { + serviceUrl = 'https://gws2.test.bceid.ca'; + serviceId = process.env.BCEID_SERVICE_ID_TEST; + } else if (env === 'prod') { + serviceUrl = 'https://gws2.bceid.ca'; + serviceId = process.env.BCEID_SERVICE_ID_PROD; + } + + const xml = generateXML({ accountType, matchKey, serviceId }); + + try { + const { response } = await soapRequest({ + url: `${serviceUrl}/webservices/client/V10/BCeIDService.asmx?WSDL`, + headers: defaultHeaders, + xml, + timeout: 1000, + }); + + const { headers, body, statusCode } = response; + const result = await parseStringSync(body); + const data = _.get(result, 'soap:Envelope.soap:Body.0.getAccountDetailResponse.0.getAccountDetailResult.0'); + if (!data) return null; + + const status = _.get(data, 'code.0'); + if (status === 'Failed') { + const failureCode = _.get(data, 'failureCode.0'); + const message = _.get(data, 'message.0'); + log(`${failureCode}: ${message}`); + return null; + } + + const account = _.get(data, 'account.0'); + const parsed = parseAccount(account); + return parsed; + } catch (error) { + log(error); + return null; + } +}; + +const migrateSilverBceidBothToGoldStandard = async (baseAdminClient, targetAdminClient, bceidUsernames = [], env) => { + if (!baseAdminClient || !targetAdminClient || !env) return; + + for (let x = 0; x < bceidUsernames.length; x++) { + const username = bceidUsernames[x]; + + try { + const baseUsers = await baseAdminClient.users.find({ realm: '_bceid', username, max: 1 }); + if (baseUsers.length === 0) { + log(`not found ${username}`); + continue; + } + + const baseUser = baseUsers[0]; + if (!baseUser.attributes.bceid_userid) { + log(`no user guid ${username}`); + continue; + } + + const baseBceidGuid = baseUser.attributes.bceid_userid[0]; + + const details = + (await fetchBceidUser({ accountType: 'Business', matchKey: baseBceidGuid, env })) || + (await fetchBceidUser({ accountType: 'Individual', matchKey: baseBceidGuid, env })); + + if (!details) { + log(`not found in bceid web service ${username}`); + continue; + } + + const commonUserData = { + enabled: true, + email: baseUser.email, + firstName: '', + lastName: '', + attributes: { + display_name: (baseUser.attributes.displayName && baseUser.attributes.displayName[0]) || '', + bceid_user_guid: details.guid, + bceid_username: details.userId, + bceid_type: details.type, + }, + }; + + let targetBceidUser = await targetAdminClient.users.create({ + ...commonUserData, + realm: 'bceidboth', + username: details.guid, + }); + + targetBceidUser = await targetAdminClient.users.findOne({ realm: 'bceidboth', id: targetBceidUser.id }); + + await targetAdminClient.users.addToFederatedIdentity({ + realm: 'bceidboth', + id: targetBceidUser.id, + federatedIdentityId: 'bceidboth', + federatedIdentity: { + userId: details.guid, + userName: details.guid, + identityProvider: 'bceidboth', + }, + }); + + const targetStandardUser = await targetAdminClient.users.create({ + ...commonUserData, + realm: 'standard', + username: `${baseBceidGuid}@bceidboth`, + }); + + await targetAdminClient.users.addToFederatedIdentity({ + realm: 'standard', + id: targetStandardUser.id, + federatedIdentityId: 'bceidboth', + federatedIdentity: { + userId: targetBceidUser.id, + userName: targetBceidUser.username, + identityProvider: 'bceidboth', + }, + }); + + log(`${username} created`); + } catch (err) { + log(`error with: ${username}`); + handleError(err); + } + } +}; + +module.exports = { migrateSilverBceidBothToGoldStandard }; diff --git a/scripts/migrations/mds.js b/scripts/migrations/mds.js index 6ae83885..587054d4 100644 --- a/scripts/migrations/mds.js +++ b/scripts/migrations/mds.js @@ -6,9 +6,10 @@ const Confirm = require('prompt-confirm'); const { getAdminClient } = require('../keycloak-core'); const { handleError, ignoreError } = require('../helpers'); const { migrateSilverIdirToGoldStandard } = require('./helpers/migrate-target-idir-users'); -const { baseEnv, baseRealm, targetEnv, targetRealm = 'standard', targetClient, auto } = argv; +const { migrateSilverBceidBothToGoldStandard } = require('./helpers/migrate-target-bceidboth-users'); +const { baseEnv, baseRealm, targetEnv, contextEnv, targetRealm = 'standard', targetClient, totp, auto } = argv; -const rolesToExclude = ['uma_authorization', 'offline_access']; +const rolesToExclude = ['admin', 'uma_authorization', 'offline_access']; const idpToRealmMap = { idir: 'idir', bceid: '_bceid', @@ -25,17 +26,27 @@ const suffixMap = { }; async function main() { - if (!baseEnv || !baseRealm || !targetEnv || !targetClient) { + if (!baseEnv || !baseRealm || !targetEnv || !contextEnv || !targetClient) { console.info(` - Usages: - node migrations/mds --base-env --base-realm --target-env --target-client [--target-realm ] [--auto] + Usage: + node migrations/mds --base-env --base-realm --target-env --context-env --target-client [--target-realm ] [--totp ] [--auto] + + Flags: + --base-env Base Keycloak environment to migrate users from + --base-realm Base realm of the base Keycloak environment to migrate users from + --target-env Target Keycloak environment to migrate users to + --target-realm Target realm of the target Keycloak environment to migrate users to; Optional, default to 'standard' + --context-env Contextual Keycloak environment; used to fetch BCeID users from BCeID web service + --target-client Target client of the target realm to migrate users with the associated client roles. + --totp Time-based One-time Password (TOTP) passed into the Keycloak auth call of the base environment; Optional + --auto Skips the confirmation before running the script `); return; } try { - const baseAdminClient = await getAdminClient(baseEnv, { totp: '657347' }); + const baseAdminClient = await getAdminClient(baseEnv, { totp }); const targetAdminClient = await getAdminClient(targetEnv); if (!baseAdminClient || !targetAdminClient) return; @@ -99,7 +110,6 @@ async function main() { ? await baseAdminClient.groups.listMembers({ realm: baseRealm, id: roleMapping.id }) : await baseAdminClient.roles.findUsersWithRole({ realm: baseRealm, name: roleMapping.name }); - // masterRoleMappings.push({ name: role.name, children: roleMappings.map((mapping) => mapping.name) }); users.forEach((user) => { if (!baseUserMap[user.id]) baseUserMap[user.id] = { ...user, roles: [] }; baseUserMap[user.id].roles.push(roleMapping.name); @@ -109,65 +119,87 @@ async function main() { const allBaseUsers = Object.values(baseUserMap); console.log('Step 3: find the matching Gold standard users'); - const idpMap = {}; + let idpMap = {}; + let userReport = {}; + let validUserMeta = []; - const userReport = { - found: [], - 'no-idp': [], - 'no-guid': [], - }; + const generateUserReport = async () => { + idpMap = {}; - const validUserMeta = []; + userReport = { + found: [], + 'no-idp': [], + 'no-guid': [], + }; - for (let x = 0; x < allBaseUsers.length; x++) { - const buser = allBaseUsers[x]; - const links = await baseAdminClient.users.listFederatedIdentities({ - realm: baseRealm, - id: buser.id, - }); + validUserMeta = []; - if (links.length === 0) { - userReport['no-idp'].push(buser.username); - continue; - } + for (let x = 0; x < allBaseUsers.length; x++) { + const buser = allBaseUsers[x]; + const links = await baseAdminClient.users.listFederatedIdentities({ + realm: baseRealm, + id: buser.id, + }); - const { identityProvider, userId } = links[0]; - const parentRealmName = idpToRealmMap[identityProvider]; - if (!parentRealmName) continue; + if (links.length === 0) { + userReport['no-idp'].push(buser.username); + continue; + } - const parentUser = await baseAdminClient.users.findOne({ realm: parentRealmName, id: userId }); - const buserGuid = _.get(parentUser, `attributes.${idpToGuidKeyMap[identityProvider]}.0`); + const { identityProvider, userId } = links[0]; + const parentRealmName = idpToRealmMap[identityProvider]; + if (!parentRealmName) continue; - if (!buserGuid) { - userReport['no-guid'].push(buser.username); - continue; - } + const parentUser = await baseAdminClient.users.findOne({ realm: parentRealmName, id: userId }); + const buserGuid = _.get(parentUser, `attributes.${idpToGuidKeyMap[identityProvider]}.0`); - if (!idpMap[identityProvider]) idpMap[identityProvider] = 0; - idpMap[identityProvider]++; + if (!buserGuid) { + userReport['no-guid'].push(buser.username); + continue; + } - let tusers = await targetAdminClient.users.find({ - realm: 'standard', - username: `${buserGuid}@${suffixMap[identityProvider]}`, - exact: true, - }); + if (!idpMap[identityProvider]) idpMap[identityProvider] = 0; + idpMap[identityProvider]++; + + let tusers = await targetAdminClient.users.find({ + realm: 'standard', + username: `${buserGuid}@${suffixMap[identityProvider]}`, + exact: true, + }); - if (tusers.length === 0) { - const key = `not-found-${identityProvider}`; - if (!userReport[key]) userReport[key] = []; - userReport[key].push(buser.username); - } else { - userReport['found'].push(buser.username); - validUserMeta.push({ baseUserId: buser.id, targetUserId: tusers[0].id }); + if (tusers.length === 0) { + const key = `not-found-${identityProvider}`; + const keyParent = `not-found-${identityProvider}-parent`; + if (!userReport[key]) userReport[key] = []; + if (!userReport[keyParent]) userReport[keyParent] = []; + userReport[key].push(buser.username); + userReport[keyParent].push(parentUser.username); + } else { + userReport['found'].push(buser.username); + validUserMeta.push({ baseUserId: buser.id, targetUserId: tusers[0].id }); + } } - } + }; + await generateUserReport(); console.log('Step 4: migrate missing IDIR users'); - if (userReport['not-found-idir']) - await migrateSilverIdirToGoldStandard(baseAdminClient, targetAdminClient, userReport['not-found-idir']); + if (userReport['not-found-idir-parent']) + await migrateSilverIdirToGoldStandard(baseAdminClient, targetAdminClient, userReport['not-found-idir-parent']); + + console.log('Step 5: migrate missing BCeID Both users'); + if (userReport['not-found-bceid-parent']) + await migrateSilverBceidBothToGoldStandard( + baseAdminClient, + targetAdminClient, + userReport['not-found-bceid-parent'], + contextEnv, + ); + + console.log('Step 6: re-match Gold standard users after migrating missing users'); + await generateUserReport(); const targetRoleMap = {}; - console.log('Step 5: create client level roles in the target realm'); + console.log('Step 7: create client level roles in the target realm'); for (let x = 0; x < masterRoleMappings.length; x++) { const roleMapping = masterRoleMappings[x]; @@ -197,7 +229,7 @@ async function main() { targetRoleMap[roleMapping.name] = role; } - console.log('Step 6: create composite role mappings in the target realm'); + console.log('Step 8: create composite role mappings in the target realm'); for (let x = 0; x < masterRoleMappings.length; x++) { const roleMapping = masterRoleMappings[x]; @@ -228,7 +260,7 @@ async function main() { await targetAdminClient.roles.createComposite({ realm: targetRealm, roleId: role.id }, rolesToAdd); } - console.log('Step 7: create user role mappings in the target realm'); + console.log('Step 9: create user role mappings in the target realm'); for (let x = 0; x < validUserMeta.length; x++) { const meta = validUserMeta[x]; diff --git a/scripts/package.json b/scripts/package.json index b6a7fe95..9388548f 100644 --- a/scripts/package.json +++ b/scripts/package.json @@ -8,10 +8,12 @@ "devDependencies": { "axios": "^0.21.4", "dotenv": "^10.0.0", + "easy-soap-request": "^5.2.0", "jws": "^4.0.0", "keycloak-admin": "^1.14.22", "lodash": "^4.17.21", "prompt-confirm": "^2.0.4", + "xml2js": "^0.4.23", "yargs": "^17.2.1" } } diff --git a/scripts/yarn.lock b/scripts/yarn.lock index 25b33e76..9ccab456 100644 --- a/scripts/yarn.lock +++ b/scripts/yarn.lock @@ -251,6 +251,11 @@ arr-swap@^1.0.1: dependencies: is-number "^3.0.0" +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== + axios@^0.21.0, axios@^0.21.4: version "0.21.4" resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575" @@ -258,6 +263,15 @@ axios@^0.21.0, axios@^0.21.4: dependencies: follow-redirects "^1.14.0" +axios@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.1.3.tgz#8274250dada2edf53814ed7db644b9c2866c1e35" + integrity sha512-00tXVRwKx/FZr/IDVFt4C+f9FYairX517WoGCL6dpOntqLkZofjhu43F/Xl44UOpqa+9sLFDrG/XAnFsUYgkDA== + dependencies: + follow-redirects "^1.15.0" + form-data "^4.0.0" + proxy-from-env "^1.1.0" + base64-js@1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" @@ -330,6 +344,13 @@ color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +combined-stream@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + component-emitter@^1.2.1: version "1.3.0" resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" @@ -381,11 +402,23 @@ define-property@^2.0.2: is-descriptor "^1.0.2" isobject "^3.0.1" +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== + dotenv@^10.0.0: version "10.0.0" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81" integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q== +easy-soap-request@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/easy-soap-request/-/easy-soap-request-5.2.0.tgz#34b04b44944d172a82ff03c0293844370c4327d7" + integrity sha512-oWP3+UXuaiiP+Jc1zhK1hzDwyqLh6rwqKW/+AaXSkaZFYpCyXqMya+zNTJYAFVNBMiZEPwSTtb44uoy90PFl7Q== + dependencies: + axios "^1.1.2" + ecdsa-sig-formatter@1.0.11: version "1.0.11" resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf" @@ -425,6 +458,11 @@ follow-redirects@^1.14.0: resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.3.tgz#6ada78118d8d24caee595595accdc0ac6abd022e" integrity sha512-3MkHxknWMUtb23apkgz/83fDoe+y+qr0TdgacGIA7bew+QLBo3vdgEN2xEsuXNivpFy4CyDhBBZnNZOtalmenw== +follow-redirects@^1.15.0: + version "1.15.2" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" + integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== + for-in@^0.1.3: version "0.1.8" resolved "https://registry.yarnpkg.com/for-in/-/for-in-0.1.8.tgz#d8773908e31256109952b1fdb9b3fa867d2775e1" @@ -442,6 +480,15 @@ for-own@^1.0.0: dependencies: for-in "^1.0.1" +form-data@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + get-caller-file@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" @@ -652,6 +699,18 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.12: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + mixin-object@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/mixin-object/-/mixin-object-2.0.1.tgz#4fb949441dab182540f1fe035ba60e1947a5e57e" @@ -761,6 +820,11 @@ prompt-question@^5.0.1: koalas "^1.0.2" prompt-choices "^4.0.5" +proxy-from-env@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" + integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== + query-string@^6.13.7: version "6.14.1" resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.14.1.tgz#7ac2dca46da7f309449ba0f86b1fd28255b0c86a" @@ -815,6 +879,11 @@ safe-buffer@^5.0.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== +sax@>=0.6.0: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + set-getter@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/set-getter/-/set-getter-0.1.1.tgz#a3110e1b461d31a9cfc8c5c9ee2e9737ad447102" @@ -964,6 +1033,19 @@ wrap-ansi@^7.0.0: string-width "^4.1.0" strip-ansi "^6.0.0" +xml2js@^0.4.23: + version "0.4.23" + resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66" + integrity sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug== + dependencies: + sax ">=0.6.0" + xmlbuilder "~11.0.0" + +xmlbuilder@~11.0.0: + version "11.0.1" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" + integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== + y18n@^5.0.5: version "5.0.8" resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" From 62dda7249ab0877fa642a4a7513dcc58b9764109 Mon Sep 17 00:00:00 2001 From: Junmin Ahn Date: Mon, 7 Nov 2022 09:08:50 -0800 Subject: [PATCH 026/118] feat: add a post login flow to assign default role --- .../ClientLoginRoleBinding.java | 59 +++++++++++++ .../ClientLoginRoleBindingFactory.java | 82 +++++++++++++++++++ ...ycloak.authentication.AuthenticatorFactory | 1 + 3 files changed, 142 insertions(+) create mode 100755 docker/keycloak/extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/authenticators/ClientLoginRoleBinding.java create mode 100644 docker/keycloak/extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/authenticators/ClientLoginRoleBindingFactory.java diff --git a/docker/keycloak/extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/authenticators/ClientLoginRoleBinding.java b/docker/keycloak/extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/authenticators/ClientLoginRoleBinding.java new file mode 100755 index 00000000..34f6f41d --- /dev/null +++ b/docker/keycloak/extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/authenticators/ClientLoginRoleBinding.java @@ -0,0 +1,59 @@ +package com.github.bcgov.keycloak.authenticators; + +import java.util.Objects; +import java.util.Optional; +import org.keycloak.authentication.AuthenticationFlowContext; +import org.keycloak.authentication.Authenticator; +import org.keycloak.models.ClientModel; +import org.keycloak.models.KeycloakSession; +import org.keycloak.models.RealmModel; +import org.keycloak.models.RoleModel; +import org.keycloak.models.UserModel; +import org.keycloak.sessions.AuthenticationSessionModel; + +/** @author Junmin Ahn */ +public class ClientLoginRoleBinding implements Authenticator { + @Override + public void authenticate(AuthenticationFlowContext context) { + AuthenticationSessionModel session = context.getAuthenticationSession(); + ClientModel client = session.getClient(); + RealmModel realm = session.getRealm(); + UserModel user = session.getAuthenticatedUser(); + + String targetRoleName = "client-" + client.getClientId(); + RoleModel clientRole = realm.getRole(targetRoleName); + if (clientRole == null) { + clientRole = realm.addRole(targetRoleName); + } + + Optional assignedRole = + user.getRealmRoleMappingsStream() + .filter(role -> Objects.equals(targetRoleName, role.getName())) + .findFirst(); + + if (!assignedRole.isPresent()) { + user.grantRole(clientRole); + } + + context.success(); + } + + @Override + public void action(AuthenticationFlowContext context) {} + + @Override + public boolean requiresUser() { + return false; + } + + @Override + public boolean configuredFor(KeycloakSession session, RealmModel realm, UserModel user) { + return true; + } + + @Override + public void setRequiredActions(KeycloakSession session, RealmModel realm, UserModel user) {} + + @Override + public void close() {} +} diff --git a/docker/keycloak/extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/authenticators/ClientLoginRoleBindingFactory.java b/docker/keycloak/extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/authenticators/ClientLoginRoleBindingFactory.java new file mode 100644 index 00000000..cbfe4444 --- /dev/null +++ b/docker/keycloak/extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/authenticators/ClientLoginRoleBindingFactory.java @@ -0,0 +1,82 @@ +package com.github.bcgov.keycloak.authenticators; + +import java.util.Collections; +import java.util.List; +import org.keycloak.Config; +import org.keycloak.OAuth2Constants; +import org.keycloak.authentication.Authenticator; +import org.keycloak.authentication.AuthenticatorFactory; +import org.keycloak.authentication.DisplayTypeAuthenticatorFactory; +import org.keycloak.authentication.authenticators.AttemptedAuthenticator; +import org.keycloak.models.AuthenticationExecutionModel.Requirement; +import org.keycloak.models.KeycloakSession; +import org.keycloak.models.KeycloakSessionFactory; +import org.keycloak.provider.ProviderConfigProperty; + +/** @author Junmin Ahn */ +public class ClientLoginRoleBindingFactory + implements AuthenticatorFactory, DisplayTypeAuthenticatorFactory { + + protected static final Requirement[] REQUIREMENT_CHOICES = {Requirement.REQUIRED}; + + @Override + public String getId() { + return "client-login-role-binding"; + } + + @Override + public String getDisplayType() { + return "Client Login Role Binding"; + } + + @Override + public String getHelpText() { + return "assign the authenticated user the realm-level role for the client"; + } + + @Override + public Authenticator create(KeycloakSession session) { + return new ClientLoginRoleBinding(); + } + + @Override + public Authenticator createDisplay(KeycloakSession session, String displayType) { + if (displayType == null) return new ClientLoginRoleBinding(); + if (!OAuth2Constants.DISPLAY_CONSOLE.equalsIgnoreCase(displayType)) return null; + return AttemptedAuthenticator.SINGLETON; // ignore this authenticator + } + + @Override + public Requirement[] getRequirementChoices() { + return REQUIREMENT_CHOICES; + } + + @Override + public List getConfigProperties() { + return Collections.emptyList(); + } + + @Override + public String getReferenceCategory() { + return null; + } + + @Override + public boolean isConfigurable() { + return false; + } + + @Override + public boolean isUserSetupAllowed() { + return false; + } + + @Override + public void init(Config.Scope config) {} + + @Override + public void postInit(KeycloakSessionFactory factory) {} + + @Override + public void close() {} +} diff --git a/docker/keycloak/extensions-7.6/services/src/main/resources/META-INF/services/org.keycloak.authentication.AuthenticatorFactory b/docker/keycloak/extensions-7.6/services/src/main/resources/META-INF/services/org.keycloak.authentication.AuthenticatorFactory index 4a0d7cb8..8ab8ef6c 100755 --- a/docker/keycloak/extensions-7.6/services/src/main/resources/META-INF/services/org.keycloak.authentication.AuthenticatorFactory +++ b/docker/keycloak/extensions-7.6/services/src/main/resources/META-INF/services/org.keycloak.authentication.AuthenticatorFactory @@ -1,6 +1,7 @@ com.github.bcgov.keycloak.authenticators.IdentityProviderStopAuthenticatorFactory com.github.bcgov.keycloak.authenticators.CookieStopAuthenticatorFactory com.github.bcgov.keycloak.authenticators.ClientLoginAuthenticatorFactory +com.github.bcgov.keycloak.authenticators.ClientLoginRoleBindingFactory com.github.bcgov.keycloak.authenticators.UserAttributeAuthenticatorFactory com.github.bcgov.keycloak.authenticators.broker.IdpDeleteUserIfDuplicateAuthenticatorFactory com.github.bcgov.keycloak.authenticators.browser.IdentityProviderStopFormFactory From 34133a74df296e13eb1b5ae0d51832821f90a659 Mon Sep 17 00:00:00 2001 From: Junmin Ahn Date: Wed, 9 Nov 2022 10:30:53 -0800 Subject: [PATCH 027/118] chore: update sandbox keycloak values --- helm/keycloak/deploy-b861c7-test-4.sh | 2 +- helm/keycloak/deploy-b861c7-test-5.sh | 2 +- helm/keycloak/deploy-b861c7-test-6.sh | 2 +- helm/keycloak/values-b861c7-test-4.yaml | 2 +- helm/keycloak/values-b861c7-test-5.yaml | 2 +- helm/keycloak/values-b861c7-test-6.yaml | 2 +- helm/keycloak/values.yaml | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/helm/keycloak/deploy-b861c7-test-4.sh b/helm/keycloak/deploy-b861c7-test-4.sh index d2445f43..f149b321 100755 --- a/helm/keycloak/deploy-b861c7-test-4.sh +++ b/helm/keycloak/deploy-b861c7-test-4.sh @@ -3,4 +3,4 @@ helm repo add sso-charts https://bcgov.github.io/sso-helm-charts helm repo update -helm upgrade --install sso-keycloak-4 sso-charts/sso-keycloak -n b861c7-test -f values-b861c7-test-4.yaml --version v1.14.1-nodep +helm upgrade --install sso-keycloak-4 sso-charts/sso-keycloak -n b861c7-test -f values-b861c7-test-4.yaml --version v1.14.2-nodep diff --git a/helm/keycloak/deploy-b861c7-test-5.sh b/helm/keycloak/deploy-b861c7-test-5.sh index 15a1e62c..c74698b2 100755 --- a/helm/keycloak/deploy-b861c7-test-5.sh +++ b/helm/keycloak/deploy-b861c7-test-5.sh @@ -3,4 +3,4 @@ helm repo add sso-charts https://bcgov.github.io/sso-helm-charts helm repo update -helm upgrade --install sso-keycloak-5 sso-charts/sso-keycloak -n b861c7-test -f values-b861c7-test-5.yaml --version v1.14.0-nodep +helm upgrade --install sso-keycloak-5 sso-charts/sso-keycloak -n b861c7-test -f values-b861c7-test-5.yaml --version v1.14.2-nodep diff --git a/helm/keycloak/deploy-b861c7-test-6.sh b/helm/keycloak/deploy-b861c7-test-6.sh index 81dd4da3..90968273 100755 --- a/helm/keycloak/deploy-b861c7-test-6.sh +++ b/helm/keycloak/deploy-b861c7-test-6.sh @@ -3,4 +3,4 @@ helm repo add sso-charts https://bcgov.github.io/sso-helm-charts helm repo update -helm upgrade --install sso-keycloak-6 sso-charts/sso-keycloak -n b861c7-test -f values-b861c7-test-6.yaml --version v1.14.0-nodep +helm upgrade --install sso-keycloak-6 sso-charts/sso-keycloak -n b861c7-test -f values-b861c7-test-6.yaml --version v1.14.2-nodep diff --git a/helm/keycloak/values-b861c7-test-4.yaml b/helm/keycloak/values-b861c7-test-4.yaml index 95c143f2..2ca7ea41 100644 --- a/helm/keycloak/values-b861c7-test-4.yaml +++ b/helm/keycloak/values-b861c7-test-4.yaml @@ -2,7 +2,7 @@ replicaCount: 1 image: repository: ghcr.io/bcgov/sso - tag: 7.6.5-build.15 + tag: 7.6.5-build.16 pullPolicy: IfNotPresent rollingUpdate: diff --git a/helm/keycloak/values-b861c7-test-5.yaml b/helm/keycloak/values-b861c7-test-5.yaml index 5c27b4ab..b52dcfaf 100644 --- a/helm/keycloak/values-b861c7-test-5.yaml +++ b/helm/keycloak/values-b861c7-test-5.yaml @@ -2,7 +2,7 @@ replicaCount: 1 image: repository: ghcr.io/bcgov/sso - tag: 7.6.5-build.15 + tag: 7.6.5-build.16 pullPolicy: IfNotPresent rollingUpdate: diff --git a/helm/keycloak/values-b861c7-test-6.yaml b/helm/keycloak/values-b861c7-test-6.yaml index ea315386..792ca1c5 100644 --- a/helm/keycloak/values-b861c7-test-6.yaml +++ b/helm/keycloak/values-b861c7-test-6.yaml @@ -2,7 +2,7 @@ replicaCount: 1 image: repository: ghcr.io/bcgov/sso - tag: 7.6.5-build.15 + tag: 7.6.5-build.16 pullPolicy: IfNotPresent rollingUpdate: diff --git a/helm/keycloak/values.yaml b/helm/keycloak/values.yaml index c00810c1..3a8f49e5 100644 --- a/helm/keycloak/values.yaml +++ b/helm/keycloak/values.yaml @@ -39,7 +39,7 @@ postgres: max: 20 annotations: - timeout: null + timeout: # see https://github.com/keycloak/keycloak-containers/blob/master/server/README.md#start-a-keycloak-instance-with-custom-command-line-options additionalServerOptions: "-Dkeycloak.profile.feature.authorization=enabled -Djboss.persistent.log.dir=/var/log/eap" From 6a5d57b9faf6e3178aea126d3fb15a6cc3142abd Mon Sep 17 00:00:00 2001 From: Junmin Ahn Date: Wed, 9 Nov 2022 10:34:11 -0800 Subject: [PATCH 028/118] chore: update mds script to migrate more bceid attributes --- .../helpers/migrate-target-bceidboth-users.js | 9 +++- scripts/migrations/test-bceid-webservice.js | 41 +++++++++++++++++++ 2 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 scripts/migrations/test-bceid-webservice.js diff --git a/scripts/migrations/helpers/migrate-target-bceidboth-users.js b/scripts/migrations/helpers/migrate-target-bceidboth-users.js index cd46ce54..9d0fdbfe 100644 --- a/scripts/migrations/helpers/migrate-target-bceidboth-users.js +++ b/scripts/migrations/helpers/migrate-target-bceidboth-users.js @@ -42,8 +42,11 @@ const parseAccount = (data) => { const userId = _.get(data, 'userId.0.value.0'); const displayName = _.get(data, 'displayName.0.value.0'); const type = _.get(data, 'type.0.code.0'); + const email = _.get(data, 'contact.0.email.0.value.0'); + const businessGuid = _.get(data, 'business.0.guid.0.value.0'); + const businessLegalName = _.get(data, 'business.0.legalName.0.value.0'); - return { guid, userId, displayName, type }; + return { guid, userId, displayName, type, email, businessGuid, businessLegalName }; }; const fetchBceidUser = async ({ accountType = 'Business', matchKey = '', env = 'dev' }) => { @@ -132,6 +135,8 @@ const migrateSilverBceidBothToGoldStandard = async (baseAdminClient, targetAdmin bceid_user_guid: details.guid, bceid_username: details.userId, bceid_type: details.type, + bceid_business_guid: details.businessGuid, + bceid_business_name: details.businessLegalName, }, }; @@ -179,4 +184,4 @@ const migrateSilverBceidBothToGoldStandard = async (baseAdminClient, targetAdmin } }; -module.exports = { migrateSilverBceidBothToGoldStandard }; +module.exports = { fetchBceidUser, migrateSilverBceidBothToGoldStandard }; diff --git a/scripts/migrations/test-bceid-webservice.js b/scripts/migrations/test-bceid-webservice.js new file mode 100644 index 00000000..8bdf0097 --- /dev/null +++ b/scripts/migrations/test-bceid-webservice.js @@ -0,0 +1,41 @@ +const _ = require('lodash'); +const { argv } = require('yargs'); +const Confirm = require('prompt-confirm'); +const { handleError, ignoreError } = require('../helpers'); +const { fetchBceidUser } = require('./helpers/migrate-target-bceidboth-users'); +const { type, search, env, auto } = argv; + +async function main() { + if (!env) { + console.info(` + Usage: + node migrations/test-bceid-webservice --type --search --env [--auto] + + Flags: + --env BCeID Client environment; dev | test | prod + --type BCeID account type; Business | Individual + --search BCeID account GUID to search for + --auto Skips the confirmation before running the script + `); + + return; + } + + try { + if (!auto) { + const prompt = new Confirm(`Are you sure to proceed?`); + const answer = await prompt.run(); + if (!answer) return; + } + + const result = await fetchBceidUser({ accountType: type, matchKey: search, env }); + console.log('result', result); + + process.exit(0); + } catch (err) { + handleError(err); + process.exit(1); + } +} + +main(); From b86cfe4c7c5aa6789d3fd8bfd04eb4d564a84e81 Mon Sep 17 00:00:00 2001 From: Junmin Ahn Date: Wed, 9 Nov 2022 16:04:00 -0800 Subject: [PATCH 029/118] chore: test disabling impersonation in sandbox dev --- helm/keycloak/values-b861c7-test-4.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/helm/keycloak/values-b861c7-test-4.yaml b/helm/keycloak/values-b861c7-test-4.yaml index 2ca7ea41..c1e6b5a0 100644 --- a/helm/keycloak/values-b861c7-test-4.yaml +++ b/helm/keycloak/values-b861c7-test-4.yaml @@ -17,6 +17,8 @@ project: sso-keycloak nameOverride: sso-keycloak-4 fullnameOverride: sso-keycloak-4 +additionalServerOptions: "-Dkeycloak.profile.feature.impersonation=disabled -Djboss.persistent.log.dir=/var/log/eap" + postgres: host: sso-patroni database: ssokeycloak4 From ab514f6559964f4a5722b39ad350bb4118e6780e Mon Sep 17 00:00:00 2001 From: Junmin Ahn Date: Wed, 9 Nov 2022 20:31:45 -0800 Subject: [PATCH 030/118] chore: exclude realm level groups properly --- .gitignore | 1 + scripts/migrations/mds.js | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index bd8a424f..1d3c0104 100644 --- a/.gitignore +++ b/.gitignore @@ -51,3 +51,4 @@ screen_shots saml_trace results screenshots +mds.json diff --git a/scripts/migrations/mds.js b/scripts/migrations/mds.js index 587054d4..e4388ad4 100644 --- a/scripts/migrations/mds.js +++ b/scripts/migrations/mds.js @@ -71,11 +71,13 @@ async function main() { for (let x = 0; x < baseGroups.length; x++) { const group = baseGroups[x]; - const roleMappings = await baseAdminClient.groups.listRealmRoleMappings({ + let roleMappings = await baseAdminClient.groups.listRealmRoleMappings({ realm: baseRealm, id: group.id, }); + roleMappings = roleMappings.filter((mapping) => !rolesToExclude.includes(mapping.name)); + masterRoleMappings.push({ type: 'group', id: group.id, From ddf063dc38b904121c3282dfa1a53756a96563fb Mon Sep 17 00:00:00 2001 From: Junmin Ahn Date: Thu, 10 Nov 2022 10:56:58 -0800 Subject: [PATCH 031/118] feat: add a script to upsert github users in gold --- scripts/.env.example | 2 + scripts/keycloak-core.js | 7 +- scripts/keycloak-gold-upsert-github-users.js | 159 +++++++ scripts/package.json | 1 + scripts/yarn.lock | 449 +++++++++++++++++++ 5 files changed, 617 insertions(+), 1 deletion(-) create mode 100644 scripts/keycloak-gold-upsert-github-users.js diff --git a/scripts/.env.example b/scripts/.env.example index 63e84794..047d363d 100644 --- a/scripts/.env.example +++ b/scripts/.env.example @@ -40,3 +40,5 @@ BCEID_REQUESTER_IDIR_GUID= BCEID_SERVICE_ID_DEV= BCEID_SERVICE_ID_TEST= BCEID_SERVICE_ID_PROD= + +GITHUB_PATH= diff --git a/scripts/keycloak-core.js b/scripts/keycloak-core.js index 5d8c2141..9b6f5b66 100644 --- a/scripts/keycloak-core.js +++ b/scripts/keycloak-core.js @@ -3,6 +3,7 @@ const axios = require('axios'); const jws = require('jws'); const dotenv = require('dotenv'); const KcAdminClient = require('keycloak-admin').default; +const { Octokit, App } = require('octokit'); dotenv.config(); @@ -128,4 +129,8 @@ async function getAdminClient(env = 'dev', { totp = '' } = {}) { } } -module.exports = { getAdminClient, getRealmUrl, getOidcConfiguration }; +const getGitHubClient = () => { + return new Octokit({ auth: process.env.GITHUB_PATH }); +}; + +module.exports = { getAdminClient, getRealmUrl, getOidcConfiguration, getGitHubClient }; diff --git a/scripts/keycloak-gold-upsert-github-users.js b/scripts/keycloak-gold-upsert-github-users.js new file mode 100644 index 00000000..e3d5c673 --- /dev/null +++ b/scripts/keycloak-gold-upsert-github-users.js @@ -0,0 +1,159 @@ +const _ = require('lodash'); +const { argv } = require('yargs'); +const Confirm = require('prompt-confirm'); +const { getAdminClient, getGitHubClient } = require('./keycloak-core'); +const { handleError, ignoreError } = require('./helpers'); +const { env, auto } = argv; + +async function main() { + if (!env || !['alpha', 'beta', 'gamma'].includes(env)) { + console.info(` + Usages: + node keycloak-gold-upsert-github-users --env [--auto] + + Examples: + node keycloak-gold-upsert-github-users.js --env alpha + `); + + return; + } + + try { + const kcAdminClient = await getAdminClient(env); + if (!kcAdminClient) return; + + const ghClient = getGitHubClient(); + if (!ghClient) return; + + if (!auto) { + const prompt = new Confirm(`Are you sure to proceed?`); + const answer = await prompt.run(); + if (!answer) return; + } + const max = 500; + let first = 0; + let total = 0; + + while (true) { + const users = await kcAdminClient.users.find({ realm: 'github', first, max }); + const count = users.length; + if (count === 0) break; + + for (let x = 0; x < users.length; x++) { + const { id, username, email, attributes } = users[x]; + + // github username is required to fetch the user from GitHub API + if (!attributes.github_username) continue; + + let ghuser = null; + + try { + ghuser = await ghClient.rest.users.getByUsername({ username: attributes.github_username }); + } catch (err) { + console.log(`user "${username}" not found in GitHub API`); + continue; + } + + if (!ghuser || !ghuser.data) { + console.log(`nonexistent user "${username}" in github realm`); + continue; + } + + // note that `email` is not available via API + const userData = ghuser.data; + + if (username !== String(userData.id)) { + console.log(`mismatched user "${username}" in github realm`); + continue; + } + + const commonAttributes = { + github_id: userData.id, + github_username: userData.login, + display_name: userData.name, + }; + + await kcAdminClient.users.update( + { realm: 'github', id }, + { + firstName: '', + lastName: '', + attributes: { + ...attributes, + ...commonAttributes, + }, + }, + ); + + // create or update the github user in the standard realm + const upsertStandardUser = async (idp, create = false) => { + let standardUsers = await kcAdminClient.users.find({ + realm: 'standard', + username: `${userData.id}@${idp}`, + first: 0, + max: 1, + }); + + if (standardUsers.length === 0) { + if (!create) return; + + console.log(`creating ${idp} user "${username}" in standard realm...`); + + const newuser = await kcAdminClient.users.create({ + enabled: true, + realm: 'standard', + username: `${userData.id}@${idp}`, + email, + firstName: userData.name, + lastName: userData.login, + attributes: commonAttributes, + }); + + await kcAdminClient.users.addToFederatedIdentity({ + realm: 'standard', + id: newuser.id, + federatedIdentityId: idp, + federatedIdentity: { + userId: id, + userName: username, + identityProvider: idp, + }, + }); + } else { + console.log(`updating ${idp} user "${username}" in standard realm...`); + + const existingUser = standardUsers[0]; + await kcAdminClient.users.update( + { realm: 'standard', id: existingUser.id }, + { + firstName: userData.name, + lastName: userData.login, + attributes: { + ...existingUser.attributes, + ...commonAttributes, + }, + }, + ); + } + }; + + await upsertStandardUser('githubpublic', true); + await upsertStandardUser('githubbcgov'); + + total++; + } + + if (count < max) break; + + first = first + max; + } + + console.log(`${total} users upserted.`); + process.exit(0); + } catch (err) { + handleError(err); + process.exit(1); + } +} + +main(); diff --git a/scripts/package.json b/scripts/package.json index 9388548f..0d12c977 100644 --- a/scripts/package.json +++ b/scripts/package.json @@ -12,6 +12,7 @@ "jws": "^4.0.0", "keycloak-admin": "^1.14.22", "lodash": "^4.17.21", + "octokit": "^2.0.10", "prompt-confirm": "^2.0.4", "xml2js": "^0.4.23", "yargs": "^17.2.1" diff --git a/scripts/yarn.lock b/scripts/yarn.lock index 9ccab456..d4e11354 100644 --- a/scripts/yarn.lock +++ b/scripts/yarn.lock @@ -2,6 +2,266 @@ # yarn lockfile v1 +"@octokit/app@^13.0.5": + version "13.0.11" + resolved "https://registry.yarnpkg.com/@octokit/app/-/app-13.0.11.tgz#6c61b9a614e0d913e4cb0201bb0911d5115f28c0" + integrity sha512-qlUynCN1+BNYQ6VaJOMCqDdCo/2yzPixuoFnbcUThakRV+5969Tp+LTAtsZWjjb/tUHfutaAYOnsia1EGTAzfA== + dependencies: + "@octokit/auth-app" "^4.0.0" + "@octokit/auth-unauthenticated" "^3.0.0" + "@octokit/core" "^4.0.0" + "@octokit/oauth-app" "^4.0.7" + "@octokit/plugin-paginate-rest" "^5.0.0" + "@octokit/types" "^8.0.0" + "@octokit/webhooks" "^10.0.0" + +"@octokit/auth-app@^4.0.0": + version "4.0.7" + resolved "https://registry.yarnpkg.com/@octokit/auth-app/-/auth-app-4.0.7.tgz#417c327e6a7ada1e6e9651db681146f8c12728e3" + integrity sha512-hjjVCoI/+1oLminVHJPPexguYb9FP4Q60hEHExgy1uAKMMJ5Zf8iJIeRJlIIqneTb4vt7NvUTEj4YDxBLZ1FLg== + dependencies: + "@octokit/auth-oauth-app" "^5.0.0" + "@octokit/auth-oauth-user" "^2.0.0" + "@octokit/request" "^6.0.0" + "@octokit/request-error" "^3.0.0" + "@octokit/types" "^8.0.0" + "@types/lru-cache" "^5.1.0" + deprecation "^2.3.1" + lru-cache "^6.0.0" + universal-github-app-jwt "^1.0.1" + universal-user-agent "^6.0.0" + +"@octokit/auth-oauth-app@^5.0.0": + version "5.0.4" + resolved "https://registry.yarnpkg.com/@octokit/auth-oauth-app/-/auth-oauth-app-5.0.4.tgz#ebd9a38f75381093d1a5e08e05b70b94f0918277" + integrity sha512-zlWuii5hAN50vsV6SJC+uIJ7SMhyWjQMEmKJQxkmNDlieE9LjnkZnbOjqRsfcG7VO7WTl4K8ccpo/3A7Kdpmrw== + dependencies: + "@octokit/auth-oauth-device" "^4.0.0" + "@octokit/auth-oauth-user" "^2.0.0" + "@octokit/request" "^6.0.0" + "@octokit/types" "^8.0.0" + "@types/btoa-lite" "^1.0.0" + btoa-lite "^1.0.0" + universal-user-agent "^6.0.0" + +"@octokit/auth-oauth-device@^4.0.0": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@octokit/auth-oauth-device/-/auth-oauth-device-4.0.3.tgz#00ce77233517e0d7d39e42a02652f64337d9df81" + integrity sha512-KPTx5nMntKjNZzzltO3X4T68v22rd7Cp/TcLJXQE2U8aXPcZ9LFuww9q9Q5WUNSu3jwi3lRwzfkPguRfz1R8Vg== + dependencies: + "@octokit/oauth-methods" "^2.0.0" + "@octokit/request" "^6.0.0" + "@octokit/types" "^8.0.0" + universal-user-agent "^6.0.0" + +"@octokit/auth-oauth-user@^2.0.0": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@octokit/auth-oauth-user/-/auth-oauth-user-2.0.4.tgz#88f060ec678d7d493695af8d827e115dd064e212" + integrity sha512-HrbDzTPqz6GcGSOUkR+wSeF3vEqsb9NMsmPja/qqqdiGmlk/Czkxctc3KeWYogHonp62Ml4kjz2VxKawrFsadQ== + dependencies: + "@octokit/auth-oauth-device" "^4.0.0" + "@octokit/oauth-methods" "^2.0.0" + "@octokit/request" "^6.0.0" + "@octokit/types" "^8.0.0" + btoa-lite "^1.0.0" + universal-user-agent "^6.0.0" + +"@octokit/auth-token@^3.0.0": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@octokit/auth-token/-/auth-token-3.0.2.tgz#a0fc8de149fd15876e1ac78f6525c1c5ab48435f" + integrity sha512-pq7CwIMV1kmzkFTimdwjAINCXKTajZErLB4wMLYapR2nuB/Jpr66+05wOTZMSCBXP6n4DdDWT2W19Bm17vU69Q== + dependencies: + "@octokit/types" "^8.0.0" + +"@octokit/auth-unauthenticated@^3.0.0": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@octokit/auth-unauthenticated/-/auth-unauthenticated-3.0.3.tgz#2fa91ca84a8c8cec244241c2a13732fc5a404a22" + integrity sha512-IyfLo1T5GmIC9+07hHGlD3gHtZI1Bona8PLhHXUnwcYDuZt0BhjlNJDYMoPG21C4r7v7+ZSxQHBKrGgkxpYb7A== + dependencies: + "@octokit/request-error" "^3.0.0" + "@octokit/types" "^8.0.0" + +"@octokit/core@^4.0.0", "@octokit/core@^4.0.4": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@octokit/core/-/core-4.1.0.tgz#b6b03a478f1716de92b3f4ec4fd64d05ba5a9251" + integrity sha512-Czz/59VefU+kKDy+ZfDwtOIYIkFjExOKf+HA92aiTZJ6EfWpFzYQWw0l54ji8bVmyhc+mGaLUbSUmXazG7z5OQ== + dependencies: + "@octokit/auth-token" "^3.0.0" + "@octokit/graphql" "^5.0.0" + "@octokit/request" "^6.0.0" + "@octokit/request-error" "^3.0.0" + "@octokit/types" "^8.0.0" + before-after-hook "^2.2.0" + universal-user-agent "^6.0.0" + +"@octokit/endpoint@^7.0.0": + version "7.0.3" + resolved "https://registry.yarnpkg.com/@octokit/endpoint/-/endpoint-7.0.3.tgz#0b96035673a9e3bedf8bab8f7335de424a2147ed" + integrity sha512-57gRlb28bwTsdNXq+O3JTQ7ERmBTuik9+LelgcLIVfYwf235VHbN9QNo4kXExtp/h8T423cR5iJThKtFYxC7Lw== + dependencies: + "@octokit/types" "^8.0.0" + is-plain-object "^5.0.0" + universal-user-agent "^6.0.0" + +"@octokit/graphql@^5.0.0": + version "5.0.4" + resolved "https://registry.yarnpkg.com/@octokit/graphql/-/graphql-5.0.4.tgz#519dd5c05123868276f3ae4e50ad565ed7dff8c8" + integrity sha512-amO1M5QUQgYQo09aStR/XO7KAl13xpigcy/kI8/N1PnZYSS69fgte+xA4+c2DISKqUZfsh0wwjc2FaCt99L41A== + dependencies: + "@octokit/request" "^6.0.0" + "@octokit/types" "^8.0.0" + universal-user-agent "^6.0.0" + +"@octokit/oauth-app@^4.0.6", "@octokit/oauth-app@^4.0.7": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@octokit/oauth-app/-/oauth-app-4.1.0.tgz#23782e77141015a4a3483820cd339ea62e85bb85" + integrity sha512-dGZcfmwPkS3VZ9CNnvNszp6mlnbOZh9+/uPNiK/AkvSUJGXTbUVIZTkMvAjbyIFw2WlIx++hhtrTeKNJq6uMbw== + dependencies: + "@octokit/auth-oauth-app" "^5.0.0" + "@octokit/auth-oauth-user" "^2.0.0" + "@octokit/auth-unauthenticated" "^3.0.0" + "@octokit/core" "^4.0.0" + "@octokit/oauth-authorization-url" "^5.0.0" + "@octokit/oauth-methods" "^2.0.0" + "@types/aws-lambda" "^8.10.83" + fromentries "^1.3.1" + universal-user-agent "^6.0.0" + +"@octokit/oauth-authorization-url@^5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@octokit/oauth-authorization-url/-/oauth-authorization-url-5.0.0.tgz#029626ce87f3b31addb98cd0d2355c2381a1c5a1" + integrity sha512-y1WhN+ERDZTh0qZ4SR+zotgsQUE1ysKnvBt1hvDRB2WRzYtVKQjn97HEPzoehh66Fj9LwNdlZh+p6TJatT0zzg== + +"@octokit/oauth-methods@^2.0.0": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@octokit/oauth-methods/-/oauth-methods-2.0.4.tgz#6abd9593ca7f91fe5068375a363bd70abd5516dc" + integrity sha512-RDSa6XL+5waUVrYSmOlYROtPq0+cfwppP4VaQY/iIei3xlFb0expH6YNsxNrZktcLhJWSpm9uzeom+dQrXlS3A== + dependencies: + "@octokit/oauth-authorization-url" "^5.0.0" + "@octokit/request" "^6.0.0" + "@octokit/request-error" "^3.0.0" + "@octokit/types" "^8.0.0" + btoa-lite "^1.0.0" + +"@octokit/openapi-types@^14.0.0": + version "14.0.0" + resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-14.0.0.tgz#949c5019028c93f189abbc2fb42f333290f7134a" + integrity sha512-HNWisMYlR8VCnNurDU6os2ikx0s0VyEjDYHNS/h4cgb8DeOxQ0n72HyinUtdDVxJhFy3FWLGl0DJhfEWk3P5Iw== + +"@octokit/plugin-paginate-rest@^5.0.0": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-5.0.1.tgz#93d7e74f1f69d68ba554fa6b888c2a9cf1f99a83" + integrity sha512-7A+rEkS70pH36Z6JivSlR7Zqepz3KVucEFVDnSrgHXzG7WLAzYwcHZbKdfTXHwuTHbkT1vKvz7dHl1+HNf6Qyw== + dependencies: + "@octokit/types" "^8.0.0" + +"@octokit/plugin-rest-endpoint-methods@^6.0.0": + version "6.7.0" + resolved "https://registry.yarnpkg.com/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-6.7.0.tgz#2f6f17f25b6babbc8b41d2bb0a95a8839672ce7c" + integrity sha512-orxQ0fAHA7IpYhG2flD2AygztPlGYNAdlzYz8yrD8NDgelPfOYoRPROfEyIe035PlxvbYrgkfUZIhSBKju/Cvw== + dependencies: + "@octokit/types" "^8.0.0" + deprecation "^2.3.1" + +"@octokit/plugin-retry@^4.0.3": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@octokit/plugin-retry/-/plugin-retry-4.0.3.tgz#75427ba1ad92afde07af9cb0c5197f214bb036e1" + integrity sha512-tDR+4Cs9GPPNJ7/RjTEq5ty2wqjKe1hRUV7/hch+nORow5LshlHXTT1qfYNsFPw3S9szvFFAfDEFq/xwrEpL7g== + dependencies: + "@octokit/types" "^8.0.0" + bottleneck "^2.15.3" + +"@octokit/plugin-throttling@^4.0.1": + version "4.3.2" + resolved "https://registry.yarnpkg.com/@octokit/plugin-throttling/-/plugin-throttling-4.3.2.tgz#d5eb363d5282c74b2839454a87545c5f90591a80" + integrity sha512-ZaCK599h3tzcoy0Jtdab95jgmD7X9iAk59E2E7hYKCAmnURaI4WpzwL9vckImilybUGrjY1JOWJapDs2N2D3vw== + dependencies: + "@octokit/types" "^8.0.0" + bottleneck "^2.15.3" + +"@octokit/request-error@^3.0.0": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@octokit/request-error/-/request-error-3.0.2.tgz#f74c0f163d19463b87528efe877216c41d6deb0a" + integrity sha512-WMNOFYrSaX8zXWoJg9u/pKgWPo94JXilMLb2VManNOby9EZxrQaBe/QSC4a1TzpAlpxofg2X/jMnCyZgL6y7eg== + dependencies: + "@octokit/types" "^8.0.0" + deprecation "^2.0.0" + once "^1.4.0" + +"@octokit/request@^6.0.0": + version "6.2.2" + resolved "https://registry.yarnpkg.com/@octokit/request/-/request-6.2.2.tgz#a2ba5ac22bddd5dcb3f539b618faa05115c5a255" + integrity sha512-6VDqgj0HMc2FUX2awIs+sM6OwLgwHvAi4KCK3mT2H2IKRt6oH9d0fej5LluF5mck1lRR/rFWN0YIDSYXYSylbw== + dependencies: + "@octokit/endpoint" "^7.0.0" + "@octokit/request-error" "^3.0.0" + "@octokit/types" "^8.0.0" + is-plain-object "^5.0.0" + node-fetch "^2.6.7" + universal-user-agent "^6.0.0" + +"@octokit/types@^8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@octokit/types/-/types-8.0.0.tgz#93f0b865786c4153f0f6924da067fe0bb7426a9f" + integrity sha512-65/TPpOJP1i3K4lBJMnWqPUJ6zuOtzhtagDvydAWbEXpbFYA0oMKKyLb95NFZZP0lSh/4b6K+DQlzvYQJQQePg== + dependencies: + "@octokit/openapi-types" "^14.0.0" + +"@octokit/webhooks-methods@^3.0.0": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@octokit/webhooks-methods/-/webhooks-methods-3.0.1.tgz#041ed0e5728cc076e375c372dd803ded5905535f" + integrity sha512-XftYVcBxtzC2G05kdBNn9IYLtQ+Cz6ufKkjZd0DU/qGaZEFTPzM2OabXAWG5tvL0q/I+Exio1JnRiPfetiMSEw== + +"@octokit/webhooks-types@6.6.0": + version "6.6.0" + resolved "https://registry.yarnpkg.com/@octokit/webhooks-types/-/webhooks-types-6.6.0.tgz#8f6e15aca2d42f7310ffbe8b8f1799ee206dc1df" + integrity sha512-czpEwg4UA3hb0G345BVk1zMXWwX0Qdaa4F/z7C3bP6baQ9AWY/VmCYydLU+Pi4z3aOPEJYCvt9zVhZ5CutqBKw== + +"@octokit/webhooks@^10.0.0": + version "10.3.1" + resolved "https://registry.yarnpkg.com/@octokit/webhooks/-/webhooks-10.3.1.tgz#a0d0d41873fe6f16cad89a893933a96ad3dc74a6" + integrity sha512-TSGiz9+IxP8Oh8LVFwhzLYTJ+8T/U6/fC/i1/iB39izyFzoEub3wNHlsfh8A6PUbde70w2pLr/O2ELlyQdrLgg== + dependencies: + "@octokit/request-error" "^3.0.0" + "@octokit/webhooks-methods" "^3.0.0" + "@octokit/webhooks-types" "6.6.0" + aggregate-error "^3.1.0" + +"@types/aws-lambda@^8.10.83": + version "8.10.108" + resolved "https://registry.yarnpkg.com/@types/aws-lambda/-/aws-lambda-8.10.108.tgz#ddadf0d9182f2f5e689ce5fc05b5f711fad6d115" + integrity sha512-1yh1W1WoqK3lGHy+V/Fi55zobxrDHUUsluCWdMlOXkCvtsCmHPXOG+CQ2STIL4B1g6xi6I6XzxaF8V9+zeIFLA== + +"@types/btoa-lite@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@types/btoa-lite/-/btoa-lite-1.0.0.tgz#e190a5a548e0b348adb0df9ac7fa5f1151c7cca4" + integrity sha512-wJsiX1tosQ+J5+bY5LrSahHxr2wT+uME5UDwdN1kg4frt40euqA+wzECkmq4t5QbveHiJepfdThgQrPw6KiSlg== + +"@types/jsonwebtoken@^8.3.3": + version "8.5.9" + resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-8.5.9.tgz#2c064ecb0b3128d837d2764aa0b117b0ff6e4586" + integrity sha512-272FMnFGzAVMGtu9tkr29hRL6bZj4Zs1KZNeHLnKqAvp06tAIcarTMwOh8/8bz4FmKRcMxZhZNeUAQsNLoiPhg== + dependencies: + "@types/node" "*" + +"@types/lru-cache@^5.1.0": + version "5.1.1" + resolved "https://registry.yarnpkg.com/@types/lru-cache/-/lru-cache-5.1.1.tgz#c48c2e27b65d2a153b19bfc1a317e30872e01eef" + integrity sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw== + +"@types/node@*": + version "18.11.9" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.9.tgz#02d013de7058cea16d36168ef2fc653464cfbad4" + integrity sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg== + +aggregate-error@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" + integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== + dependencies: + clean-stack "^2.0.0" + indent-string "^4.0.0" + ansi-bgblack@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/ansi-bgblack/-/ansi-bgblack-0.1.1.tgz#a68ba5007887701b6aafbe3fa0dadfdfa8ee3ca2" @@ -277,6 +537,21 @@ base64-js@1.3.1: resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== +before-after-hook@^2.2.0: + version "2.2.3" + resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.2.3.tgz#c51e809c81a4e354084422b9b26bad88249c517c" + integrity sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ== + +bottleneck@^2.15.3: + version "2.19.5" + resolved "https://registry.yarnpkg.com/bottleneck/-/bottleneck-2.19.5.tgz#5df0b90f59fd47656ebe63c78a98419205cadd91" + integrity sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw== + +btoa-lite@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/btoa-lite/-/btoa-lite-1.0.0.tgz#337766da15801210fdd956c22e9c6891ab9d0337" + integrity sha512-gvW7InbIyF8AicrqWoptdW08pUxuhq8BEgowNajy9RhiE86fmGAGl+bLKo6oB8QP0CkqHLowfN0oJdKC/J6LbA== + buffer-equal-constant-time@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" @@ -296,6 +571,11 @@ choices-separator@^2.0.0: debug "^2.6.6" strip-color "^0.1.0" +clean-stack@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" + integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== + cliui@^7.0.2: version "7.0.4" resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" @@ -407,6 +687,11 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== +deprecation@^2.0.0, deprecation@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919" + integrity sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ== + dotenv@^10.0.0: version "10.0.0" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81" @@ -489,11 +774,21 @@ form-data@^4.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +fromentries@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/fromentries/-/fromentries-1.3.2.tgz#e4bca6808816bf8f93b52750f1127f5a6fd86e3a" + integrity sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg== + get-caller-file@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== +indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== + info-symbol@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/info-symbol/-/info-symbol-0.1.0.tgz#27841d72867ddb4242cd612d79c10633881c6a78" @@ -584,6 +879,11 @@ is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" +is-plain-object@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" + integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== + is-windows@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" @@ -599,6 +899,31 @@ js-sha256@0.9.0: resolved "https://registry.yarnpkg.com/js-sha256/-/js-sha256-0.9.0.tgz#0b89ac166583e91ef9123644bd3c5334ce9d0966" integrity sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA== +jsonwebtoken@^8.5.1: + version "8.5.1" + resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d" + integrity sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w== + dependencies: + jws "^3.2.2" + lodash.includes "^4.3.0" + lodash.isboolean "^3.0.3" + lodash.isinteger "^4.0.4" + lodash.isnumber "^3.0.3" + lodash.isplainobject "^4.0.6" + lodash.isstring "^4.0.1" + lodash.once "^4.0.0" + ms "^2.1.1" + semver "^5.6.0" + +jwa@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a" + integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA== + dependencies: + buffer-equal-constant-time "1.0.1" + ecdsa-sig-formatter "1.0.11" + safe-buffer "^5.0.1" + jwa@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/jwa/-/jwa-2.0.0.tgz#a7e9c3f29dae94027ebcaf49975c9345593410fc" @@ -608,6 +933,14 @@ jwa@^2.0.0: ecdsa-sig-formatter "1.0.11" safe-buffer "^5.0.1" +jws@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304" + integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA== + dependencies: + jwa "^1.4.1" + safe-buffer "^5.0.1" + jws@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/jws/-/jws-4.0.0.tgz#2d4e8cf6a318ffaa12615e9dec7e86e6c97310f4" @@ -666,6 +999,41 @@ lazy-cache@^2.0.1: dependencies: set-getter "^0.1.0" +lodash.includes@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" + integrity sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w== + +lodash.isboolean@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" + integrity sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg== + +lodash.isinteger@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" + integrity sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA== + +lodash.isnumber@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" + integrity sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw== + +lodash.isplainobject@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" + integrity sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA== + +lodash.isstring@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" + integrity sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw== + +lodash.once@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" + integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg== + lodash@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" @@ -692,6 +1060,13 @@ log-utils@^0.2.1: time-stamp "^1.0.1" warning-symbol "^0.1.0" +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + map-visit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" @@ -734,6 +1109,13 @@ mute-stream@0.0.7: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= +node-fetch@^2.6.7: + version "2.6.7" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" + integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== + dependencies: + whatwg-url "^5.0.0" + object-copy@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" @@ -750,6 +1132,27 @@ object-visit@^1.0.0: dependencies: isobject "^3.0.0" +octokit@^2.0.10: + version "2.0.10" + resolved "https://registry.yarnpkg.com/octokit/-/octokit-2.0.10.tgz#e3b991b34fba733ced82b4ddb2444aeeb7da0d2a" + integrity sha512-sI15RZVaV9iyqLLEky4i++tMM48Fo9a80zrpOXMdAtbomznBLDi/moi9mAjJg7Ii+EaSEyaWOVIh3M/Vk/a5mw== + dependencies: + "@octokit/app" "^13.0.5" + "@octokit/core" "^4.0.4" + "@octokit/oauth-app" "^4.0.6" + "@octokit/plugin-paginate-rest" "^5.0.0" + "@octokit/plugin-rest-endpoint-methods" "^6.0.0" + "@octokit/plugin-retry" "^4.0.3" + "@octokit/plugin-throttling" "^4.0.1" + "@octokit/types" "^8.0.0" + +once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + pointer-symbol@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/pointer-symbol/-/pointer-symbol-1.0.0.tgz#60f9110204ea7a929b62644a21315543cbb3d447" @@ -884,6 +1287,11 @@ sax@>=0.6.0: resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== +semver@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + set-getter@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/set-getter/-/set-getter-0.1.1.tgz#a3110e1b461d31a9cfc8c5c9ee2e9737ad447102" @@ -1001,6 +1409,24 @@ toggle-array@^1.0.1: dependencies: isobject "^3.0.0" +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== + +universal-github-app-jwt@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/universal-github-app-jwt/-/universal-github-app-jwt-1.1.0.tgz#0abaa876101cdf1d3e4c546be2768841c0c1b514" + integrity sha512-3b+ocAjjz4JTyqaOT+NNBd5BtTuvJTxWElIoeHSVelUV9J3Jp7avmQTdLKCaoqi/5Ox2o/q+VK19TJ233rVXVQ== + dependencies: + "@types/jsonwebtoken" "^8.3.3" + jsonwebtoken "^8.5.1" + +universal-user-agent@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-6.0.0.tgz#3381f8503b251c0d9cd21bc1de939ec9df5480ee" + integrity sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w== + url-join@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/url-join/-/url-join-4.0.1.tgz#b642e21a2646808ffa178c4c5fda39844e12cde7" @@ -1016,6 +1442,19 @@ warning-symbol@^0.1.0: resolved "https://registry.yarnpkg.com/warning-symbol/-/warning-symbol-0.1.0.tgz#bb31dd11b7a0f9d67ab2ed95f457b65825bbad21" integrity sha1-uzHdEbeg+dZ6su2V9Fe2WCW7rSE= +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== + +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + window-size@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/window-size/-/window-size-1.1.1.tgz#9858586580ada78ab26ecd6978a6e03115c1af20" @@ -1033,6 +1472,11 @@ wrap-ansi@^7.0.0: string-width "^4.1.0" strip-ansi "^6.0.0" +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + xml2js@^0.4.23: version "0.4.23" resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66" @@ -1051,6 +1495,11 @@ y18n@^5.0.5: resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + yargs-parser@^20.2.2: version "20.2.9" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" From 67a07f59d3460994b96f8ca7d7f7c3478fb5c9e4 Mon Sep 17 00:00:00 2001 From: Junmin Ahn Date: Thu, 10 Nov 2022 13:40:06 -0800 Subject: [PATCH 032/118] chore: add a script to populate bceid first & last names --- scripts/keycloak-gold-update-bceid-users.js | 76 +++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 scripts/keycloak-gold-update-bceid-users.js diff --git a/scripts/keycloak-gold-update-bceid-users.js b/scripts/keycloak-gold-update-bceid-users.js new file mode 100644 index 00000000..d17e4abe --- /dev/null +++ b/scripts/keycloak-gold-update-bceid-users.js @@ -0,0 +1,76 @@ +const _ = require('lodash'); +const { argv } = require('yargs'); +const Confirm = require('prompt-confirm'); +const { getAdminClient } = require('./keycloak-core'); +const { handleError, ignoreError } = require('./helpers'); +const { env, auto } = argv; + +async function updateStandardBceid(kcAdminClient, idp) { + const max = 500; + let first = 0; + let total = 0; + + while (true) { + const users = await kcAdminClient.users.find({ realm: 'standard', username: `@${idp}`, first, max }); + const count = users.length; + if (count === 0) break; + + for (let x = 0; x < users.length; x++) { + const { id, username, attributes = {} } = users[x]; + + console.log(`updating ${idp} user "${username}" in standard realm...`); + await kcAdminClient.users.update( + { realm: 'standard', id }, + { + firstName: _.get(attributes, 'display_name.0', ''), + lastName: _.get(attributes, 'bceid_username.0', ''), + attributes, + }, + ); + + total++; + } + + if (count < max) break; + + first = first + max; + } + + console.log(`${total} ${idp} users upserted.`); +} + +async function main() { + if (!env || !['alpha', 'beta', 'gamma'].includes(env)) { + console.info(` + Usages: + node keycloak-gold-update-bceid-users --env [--auto] + + Examples: + node keycloak-gold-update-bceid-users.js --env alpha + `); + + return; + } + + try { + const kcAdminClient = await getAdminClient(env); + if (!kcAdminClient) return; + + if (!auto) { + const prompt = new Confirm(`Are you sure to proceed?`); + const answer = await prompt.run(); + if (!answer) return; + } + + await updateStandardBceid(kcAdminClient, 'bceidbasic'); + await updateStandardBceid(kcAdminClient, 'bceidbusiness'); + await updateStandardBceid(kcAdminClient, 'bceidboth'); + + process.exit(0); + } catch (err) { + handleError(err); + process.exit(1); + } +} + +main(); From f1812bd328b513cc1020c892be3f99062481d9e7 Mon Sep 17 00:00:00 2001 From: Junmin Ahn Date: Thu, 10 Nov 2022 13:42:12 -0800 Subject: [PATCH 033/118] chore: fix typo --- scripts/keycloak-gold-update-bceid-users.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/keycloak-gold-update-bceid-users.js b/scripts/keycloak-gold-update-bceid-users.js index d17e4abe..b7467827 100644 --- a/scripts/keycloak-gold-update-bceid-users.js +++ b/scripts/keycloak-gold-update-bceid-users.js @@ -36,7 +36,7 @@ async function updateStandardBceid(kcAdminClient, idp) { first = first + max; } - console.log(`${total} ${idp} users upserted.`); + console.log(`${total} ${idp} users updated.`); } async function main() { From b5533a5cdcf5420aba1a5a647ac0270d085040ba Mon Sep 17 00:00:00 2001 From: Junmin Ahn Date: Mon, 14 Nov 2022 21:24:19 -0800 Subject: [PATCH 034/118] feat: add optional tooltips for idp selections --- .../browser/IdentityProviderStopForm.java | 30 ++++++++++-- .../realm-identity-provider-oidc-ext.html | 7 +++ .../theme/bcgov-idp-stopper/login/login.ftl | 30 ++++++++++-- .../bcgov-idp-stopper/login/theme.properties | 1 - .../login/theme.properties | 3 ++ .../bcgov/login/resources/css/styles.css | 48 ++++++++++++++++++- .../theme/bcgov/login/resources/js/script.js | 20 ++++++++ .../resources/theme/bcgov/login/template.ftl | 9 ++++ .../theme/bcgov/login/theme.properties | 3 ++ 9 files changed, 141 insertions(+), 10 deletions(-) create mode 100644 docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov-no-header-no-footer/login/theme.properties diff --git a/docker/keycloak/extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/authenticators/browser/IdentityProviderStopForm.java b/docker/keycloak/extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/authenticators/browser/IdentityProviderStopForm.java index 2fea1719..602d128d 100755 --- a/docker/keycloak/extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/authenticators/browser/IdentityProviderStopForm.java +++ b/docker/keycloak/extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/authenticators/browser/IdentityProviderStopForm.java @@ -1,5 +1,8 @@ package com.github.bcgov.keycloak.authenticators.browser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.util.HashMap; import java.util.List; import java.util.Map; import javax.ws.rs.core.MultivaluedMap; @@ -32,18 +35,37 @@ public void authenticate(AuthenticationFlowContext context) { context.getAuthenticationSession().getClient().getClientScopes(true); String idpkeys = ""; + Map> idpContext = new HashMap<>(); + for (IdentityProviderModel ridp : realmIdps) { String oidcAlias = ridp.getAlias(); - String samlAlias = ridp.getAlias() + "-saml"; + String samlAlias = oidcAlias + "-saml"; if (ridp.isEnabled() && (scopes.containsKey(oidcAlias) || scopes.containsKey(samlAlias))) { - idpkeys += "##" + ridp.getAlias() + "##"; + Map data = new HashMap<>(); + data.put("enabled", "true"); + + String tooltip = ridp.getConfig().get("tooltip"); + if (tooltip != null && tooltip.length() > 0) { + data.put("tooltip", tooltip); + } + + idpContext.put(oidcAlias, data); } } MultivaluedMap formData = new MultivaluedMapImpl<>(); - formData.add(AuthenticationManager.FORM_USERNAME, idpkeys); - log.tracef("allowed idps: %s", idpkeys); + + ObjectMapper objectMapper = new ObjectMapper(); + try { + String json = objectMapper.writeValueAsString(idpContext); + log.tracef("idp context: %s", json); + formData.add(AuthenticationManager.FORM_USERNAME, json); + } catch (JsonProcessingException e) { + e.printStackTrace(); + formData.add(AuthenticationManager.FORM_USERNAME, "{}"); + } + Response challengeResponse = challenge(context, formData); context.challenge(challengeResponse); } diff --git a/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-oidc-ext.html b/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-oidc-ext.html index 10a031b8..c75aae21 100755 --- a/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-oidc-ext.html +++ b/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-oidc-ext.html @@ -5,3 +5,10 @@ Does the external IDP support legacy logout redirect URI (redirect_uri)? +
+ +
+ +
+ IDP tooltip to show on the login screen. +
diff --git a/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov-idp-stopper/login/login.ftl b/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov-idp-stopper/login/login.ftl index e756eec9..29af753b 100755 --- a/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov-idp-stopper/login/login.ftl +++ b/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov-idp-stopper/login/login.ftl @@ -2,7 +2,7 @@ <@layout.registrationLayout displayMessage=!messagesPerField.existsError('username','password') displayInfo=realm.password && realm.registrationAllowed && !registrationDisabled??; section> <#if section = "header"> ${msg("loginAccountTitle")} - <#elseif section = "info" > + <#elseif section = "info"> <#if realm.password && realm.registrationAllowed && !registrationDisabled??>
@@ -11,15 +11,39 @@
- <#elseif section = "socialProviders" > + <#elseif section = "socialProviders"> <#if realm.password && social.providers??>
diff --git a/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov-idp-stopper/login/theme.properties b/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov-idp-stopper/login/theme.properties index a79a80fa..cc8fd5a0 100644 --- a/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov-idp-stopper/login/theme.properties +++ b/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov-idp-stopper/login/theme.properties @@ -1,3 +1,2 @@ parent=bcgov -import=common/keycloak kcLoginTitleType=client diff --git a/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov-no-header-no-footer/login/theme.properties b/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov-no-header-no-footer/login/theme.properties new file mode 100644 index 00000000..d1efc041 --- /dev/null +++ b/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov-no-header-no-footer/login/theme.properties @@ -0,0 +1,3 @@ +parent=bcgov +kcShowHeader=false +kcShowFooter=false diff --git a/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov/login/resources/css/styles.css b/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov/login/resources/css/styles.css index 5a92faac..a9bd3ba4 100644 --- a/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov/login/resources/css/styles.css +++ b/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov/login/resources/css/styles.css @@ -62,9 +62,7 @@ .login-pf body .login-pf-page #kc-content #kc-content-wrapper #kc-form-wrapper { width: 100%; margin-bottom: 20px; - border-bottom: 1px solid #b3b1b3; border-right: none; - padding: 10px 20px; } .login-pf body .login-pf-page #kc-content #kc-content-wrapper #kc-error-message { @@ -75,6 +73,23 @@ border-radius: 5px; } +.login-pf body .login-pf-page #kc-content #kc-content-wrapper .kc-social-provider-name { + top: 0; +} + +.login-pf body .login-pf-page #kc-content #kc-content-wrapper .kc-social-link { + display: flex; +} + +.login-pf body .login-pf-page #kc-content #kc-content-wrapper .kc-social-link > a { + width: 100%; +} + +.login-pf body .login-pf-page #kc-content #kc-content-wrapper .kc-social-link > span { + width: 40px; + padding: 6px; +} + /* HEADER */ .login-pf body > header { background-color: #036; @@ -156,6 +171,8 @@ } /* BCGOV PRIMARY BUTTON */ +#kc-form-buttons input, +#kc-social-providers .kc-social-links a[type='button'], .bcgov-primary { background-color: #003366; border: none; @@ -172,17 +189,44 @@ cursor: pointer; } +#kc-form-buttons input { + padding: 0.4rem 0.5rem; +} + +#kc-form-buttons input:hover, +#kc-social-providers .kc-social-links a[type='button']:hover, .bcgov-primary:hover { color: white !important; text-decoration-line: none; + border: none; + border-radius: 4px; opacity: 0.8; } +#kc-form-buttons input:after, +#kc-social-providers .kc-social-links a[type='button']:after, +.bcgov-primary:after { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + pointer-events: none; + content: ''; + border: none; + border-color: transparent; + border-radius: 4px; +} + +#kc-form-buttons input:focus, +#kc-social-providers .kc-social-links a[type='button']:focus, .bcgov-primary:focus { outline: 4px solid #3b99fc; outline-offset: 1px; } +#kc-form-buttons input:active, +#kc-social-providers .kc-social-links a[type='button']:active, .bcgov-primary:active { opacity: 1; } diff --git a/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov/login/resources/js/script.js b/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov/login/resources/js/script.js index 87025ba5..fa134afe 100644 --- a/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov/login/resources/js/script.js +++ b/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov/login/resources/js/script.js @@ -5,6 +5,8 @@ document.addEventListener('DOMContentLoaded', function (event) { const errorElem = document.getElementById('kc-error-message'); const titleContent = errorElem ? 'Login Error:' : 'Authenticate with:'; document.getElementById('kc-page-title').innerHTML = titleContent; + + addTooltips(); }); function updateFavIcon() { @@ -14,3 +16,21 @@ function updateFavIcon() { link.href = 'https://portal.nrs.gov.bc.ca/nrs-portal-theme/images/favicon.ico'; document.getElementsByTagName('head')[0].appendChild(link); } + +function addTooltips() { + const icons = document.getElementsByClassName('kc-social-icon'); + for (var x = 0; x < icons.length; x++) { + var elem = icons[x]; + var content = elem.getAttribute('data-tooltip'); + + if (content) { + tippy(elem, { + content, + allowHTML: true, + hideOnClick: false, + delay: [100, 100], + interactive: true, + }); + } + } +} diff --git a/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov/login/template.ftl b/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov/login/template.ftl index bad0ea45..0fba1228 100644 --- a/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov/login/template.ftl +++ b/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov/login/template.ftl @@ -29,6 +29,11 @@ + <#if properties.absoluteScripts?has_content> + <#list properties.absoluteScripts?split(' ') as script> + + + <#if scripts??> <#list scripts as script> @@ -38,6 +43,7 @@ +<#if properties.kcShowHeader == "true">
 
+
@@ -162,6 +169,7 @@
+ <#if properties.kcShowFooter == "true">
    @@ -172,6 +180,7 @@
+ diff --git a/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov/login/theme.properties b/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov/login/theme.properties index 0517d3ff..f2b6f313 100644 --- a/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov/login/theme.properties +++ b/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov/login/theme.properties @@ -2,5 +2,8 @@ parent=keycloak import=common/keycloak styles=css/login.css css/tile.css css/bcsans.css css/styles.css scripts=js/script.js +absoluteScripts=https://unpkg.com/@popperjs/core@2 https://unpkg.com/tippy.js@6 kcLoginTitleType=realm +kcShowHeader=true +kcShowFooter=true From 2ac0d68ae1e30f55835221228c2b3ab3b75d1900 Mon Sep 17 00:00:00 2001 From: Junmin Ahn Date: Tue, 15 Nov 2022 09:03:33 -0800 Subject: [PATCH 035/118] chore: add fasterxml deps --- .../keycloak/extensions-7.6/services/pom.xml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/docker/keycloak/extensions-7.6/services/pom.xml b/docker/keycloak/extensions-7.6/services/pom.xml index 33823ffd..d07f8d23 100644 --- a/docker/keycloak/extensions-7.6/services/pom.xml +++ b/docker/keycloak/extensions-7.6/services/pom.xml @@ -51,6 +51,25 @@ import + + com.fasterxml.jackson.core + jackson-core + 2.14.0 + provided + + + com.fasterxml.jackson.core + jackson-databind + 2.14.0 + provided + + + com.fasterxml.jackson.core + jackson-annotations + 2.14.0 + provided + + junit From c113957d108f90c21d524dae7f75dff5e24d803b Mon Sep 17 00:00:00 2001 From: Junmin Ahn Date: Tue, 15 Nov 2022 09:33:10 -0800 Subject: [PATCH 036/118] chore: bump github action versions --- .github/workflows/pre-commit.yml | 9 +++++---- .github/workflows/publish-image-backup-storage-test.yml | 2 +- .github/workflows/publish-image-kc-cron-job.yml | 2 +- helm/keycloak/values-b861c7-test-4.yaml | 2 +- helm/keycloak/values-b861c7-test-5.yaml | 2 +- helm/keycloak/values-b861c7-test-6.yaml | 2 +- 6 files changed, 10 insertions(+), 9 deletions(-) diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index a05d42a2..79da0171 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -6,11 +6,11 @@ jobs: pre-commit: runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install asdf uses: asdf-vm/actions/setup@v1 - name: Cache tools - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: | /home/runner/.asdf @@ -26,10 +26,11 @@ jobs: pip install -r requirements.txt asdf reshim pre-commit run --color=always --show-diff-on-failure --all-files + commitlint: runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 - - uses: wagoid/commitlint-github-action@v2 + - uses: wagoid/commitlint-github-action@v5 diff --git a/.github/workflows/publish-image-backup-storage-test.yml b/.github/workflows/publish-image-backup-storage-test.yml index 554378cf..4465d0fc 100644 --- a/.github/workflows/publish-image-backup-storage-test.yml +++ b/.github/workflows/publish-image-backup-storage-test.yml @@ -15,7 +15,7 @@ env: jobs: build-and-push-image: - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 permissions: contents: read packages: write diff --git a/.github/workflows/publish-image-kc-cron-job.yml b/.github/workflows/publish-image-kc-cron-job.yml index 540ffeab..7d421a51 100644 --- a/.github/workflows/publish-image-kc-cron-job.yml +++ b/.github/workflows/publish-image-kc-cron-job.yml @@ -24,7 +24,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Log in to the GitHub Container registry uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9 diff --git a/helm/keycloak/values-b861c7-test-4.yaml b/helm/keycloak/values-b861c7-test-4.yaml index c1e6b5a0..5a7edf02 100644 --- a/helm/keycloak/values-b861c7-test-4.yaml +++ b/helm/keycloak/values-b861c7-test-4.yaml @@ -2,7 +2,7 @@ replicaCount: 1 image: repository: ghcr.io/bcgov/sso - tag: 7.6.5-build.16 + tag: 7.6.5-build.18 pullPolicy: IfNotPresent rollingUpdate: diff --git a/helm/keycloak/values-b861c7-test-5.yaml b/helm/keycloak/values-b861c7-test-5.yaml index b52dcfaf..b66784f0 100644 --- a/helm/keycloak/values-b861c7-test-5.yaml +++ b/helm/keycloak/values-b861c7-test-5.yaml @@ -2,7 +2,7 @@ replicaCount: 1 image: repository: ghcr.io/bcgov/sso - tag: 7.6.5-build.16 + tag: 7.6.5-build.18 pullPolicy: IfNotPresent rollingUpdate: diff --git a/helm/keycloak/values-b861c7-test-6.yaml b/helm/keycloak/values-b861c7-test-6.yaml index 792ca1c5..040e08ff 100644 --- a/helm/keycloak/values-b861c7-test-6.yaml +++ b/helm/keycloak/values-b861c7-test-6.yaml @@ -2,7 +2,7 @@ replicaCount: 1 image: repository: ghcr.io/bcgov/sso - tag: 7.6.5-build.16 + tag: 7.6.5-build.18 pullPolicy: IfNotPresent rollingUpdate: From 1272ff38f3c64ff227fa9f2710df7cc62df10592 Mon Sep 17 00:00:00 2001 From: Junmin Ahn Date: Tue, 15 Nov 2022 11:05:08 -0800 Subject: [PATCH 037/118] chore: add themes to cover more scenarios --- .../login/theme.properties | 3 +++ .../theme/bcgov-idp-login/login/login.ftl | 20 +++++++++++++++++++ .../bcgov-idp-login/login/theme.properties | 1 + .../theme/bcgov-idp-stopper/login/login.ftl | 14 ++----------- .../login/theme.properties | 0 .../bcgov/login/resources/css/styles.css | 4 ++++ 6 files changed, 30 insertions(+), 12 deletions(-) create mode 100644 docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov-idp-login-no-brand/login/theme.properties create mode 100755 docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov-idp-login/login/login.ftl create mode 100644 docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov-idp-login/login/theme.properties rename docker/keycloak/extensions-7.6/themes/src/main/resources/theme/{bcgov-no-header-no-footer => bcgov-no-brand}/login/theme.properties (100%) diff --git a/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov-idp-login-no-brand/login/theme.properties b/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov-idp-login-no-brand/login/theme.properties new file mode 100644 index 00000000..684f0dbc --- /dev/null +++ b/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov-idp-login-no-brand/login/theme.properties @@ -0,0 +1,3 @@ +parent=bcgov-idp-login +kcShowHeader=false +kcShowFooter=false diff --git a/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov-idp-login/login/login.ftl b/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov-idp-login/login/login.ftl new file mode 100755 index 00000000..f5c3197a --- /dev/null +++ b/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov-idp-login/login/login.ftl @@ -0,0 +1,20 @@ +<#import "template.ftl" as layout> +<@layout.registrationLayout displayMessage=true displayInfo=false; section> + <#if section = "header"> + ${msg("loginAccountTitle")} + <#elseif section = "socialProviders"> + <#if social.providers??> +
+ +
+ + + diff --git a/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov-idp-login/login/theme.properties b/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov-idp-login/login/theme.properties new file mode 100644 index 00000000..9b4b65e8 --- /dev/null +++ b/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov-idp-login/login/theme.properties @@ -0,0 +1 @@ +parent=bcgov diff --git a/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov-idp-stopper/login/login.ftl b/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov-idp-stopper/login/login.ftl index 29af753b..945abb41 100755 --- a/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov-idp-stopper/login/login.ftl +++ b/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov-idp-stopper/login/login.ftl @@ -1,18 +1,9 @@ <#import "template.ftl" as layout> -<@layout.registrationLayout displayMessage=!messagesPerField.existsError('username','password') displayInfo=realm.password && realm.registrationAllowed && !registrationDisabled??; section> +<@layout.registrationLayout displayMessage=true displayInfo=false; section> <#if section = "header"> ${msg("loginAccountTitle")} - <#elseif section = "info"> - <#if realm.password && realm.registrationAllowed && !registrationDisabled??> -
-
- ${msg("noAccount")} ${msg("doRegister")} -
-
- <#elseif section = "socialProviders"> - <#if realm.password && social.providers??> + <#if social.providers??>
- diff --git a/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov-no-header-no-footer/login/theme.properties b/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov-no-brand/login/theme.properties similarity index 100% rename from docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov-no-header-no-footer/login/theme.properties rename to docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov-no-brand/login/theme.properties diff --git a/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov/login/resources/css/styles.css b/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov/login/resources/css/styles.css index a9bd3ba4..e1a0c77b 100644 --- a/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov/login/resources/css/styles.css +++ b/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov/login/resources/css/styles.css @@ -90,6 +90,10 @@ padding: 6px; } +.login-pf body .login-pf-page .kc-social-links { + display: block; +} + /* HEADER */ .login-pf body > header { background-color: #036; From 339f1fac22299612b71285d393a6380017fc61b9 Mon Sep 17 00:00:00 2001 From: Junmin Ahn Date: Wed, 16 Nov 2022 12:01:13 -0800 Subject: [PATCH 038/118] feat: add claim omitter mapper --- .../oidc/mappers/ClaimOmitterMapper.java | 117 ++++++++++++++++++ .../org.keycloak.protocol.ProtocolMapper | 1 + .../theme/bcgov-idp-stopper/login/login.ftl | 44 +++---- .../bcgov/login/resources/css/styles.css | 11 +- 4 files changed, 145 insertions(+), 28 deletions(-) create mode 100755 docker/keycloak/extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/protocol/oidc/mappers/ClaimOmitterMapper.java diff --git a/docker/keycloak/extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/protocol/oidc/mappers/ClaimOmitterMapper.java b/docker/keycloak/extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/protocol/oidc/mappers/ClaimOmitterMapper.java new file mode 100755 index 00000000..357930db --- /dev/null +++ b/docker/keycloak/extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/protocol/oidc/mappers/ClaimOmitterMapper.java @@ -0,0 +1,117 @@ +package com.github.bcgov.keycloak.protocol.oidc.mappers; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.jboss.logging.Logger; +import org.keycloak.models.ProtocolMapperModel; +import org.keycloak.models.UserSessionModel; +import org.keycloak.protocol.oidc.OIDCLoginProtocol; +import org.keycloak.protocol.oidc.mappers.AbstractOIDCProtocolMapper; +import org.keycloak.protocol.oidc.mappers.OIDCAccessTokenMapper; +import org.keycloak.protocol.oidc.mappers.OIDCAttributeMapperHelper; +import org.keycloak.protocol.oidc.mappers.OIDCIDTokenMapper; +import org.keycloak.protocol.oidc.mappers.UserInfoTokenMapper; +import org.keycloak.provider.ProviderConfigProperty; +import org.keycloak.representations.IDToken; + +/** @author Junmin Ahn */ +public class ClaimOmitterMapper extends AbstractOIDCProtocolMapper + implements OIDCAccessTokenMapper, OIDCIDTokenMapper, UserInfoTokenMapper { + + private static final Logger logger = Logger.getLogger(ClaimOmitterMapper.class); + + public static final String IDP_ALIASES = "identity_provider_aliases"; + public static final String TOKEN_CLAIM_NAMES = "token_claim_names"; + + private static final List configProperties = + new ArrayList(); + + static { + ProviderConfigProperty config = new ProviderConfigProperty(); + config.setName(IDP_ALIASES); + config.setLabel("Identity Provider Aliases"); + config.setHelpText(""); + config.setType(ProviderConfigProperty.STRING_TYPE); + configProperties.add(config); + + config = new ProviderConfigProperty(); + config.setName(TOKEN_CLAIM_NAMES); + config.setLabel("Token Claim Names"); + config.setHelpText("List of the token claim names to remove from the token."); + config.setType(ProviderConfigProperty.STRING_TYPE); + configProperties.add(config); + + OIDCAttributeMapperHelper.addIncludeInTokensConfig(configProperties, ClaimOmitterMapper.class); + } + + public static final String PROVIDER_ID = "omit-claim-by-idp-mapper"; + + public List getConfigProperties() { + return configProperties; + } + + @Override + public String getId() { + return PROVIDER_ID; + } + + @Override + public String getDisplayType() { + return "Omit Claims By IDPs"; + } + + @Override + public String getDisplayCategory() { + return TOKEN_MAPPER_CATEGORY; + } + + @Override + public String getHelpText() { + return "Omit one or multiple token claims"; + } + + protected void setClaim( + IDToken token, ProtocolMapperModel mappingModel, UserSessionModel userSession) { + String sessionIdpAlias = userSession.getNotes().get("identity_provider"); + String idpAliases = mappingModel.getConfig().get(IDP_ALIASES); + String[] idpAliasArr = idpAliases == null ? new String[0] : idpAliases.split(" "); + + if (idpAliasArr.length > 0) { + if (sessionIdpAlias == null || sessionIdpAlias.trim().isEmpty()) return; + if (!Arrays.asList(idpAliasArr).contains(sessionIdpAlias)) return; + } + + String tokenClaims = mappingModel.getConfig().get(TOKEN_CLAIM_NAMES); + String[] tokenClaimArr = tokenClaims == null ? new String[0] : tokenClaims.split(" "); + + if (tokenClaimArr.length == 0) return; + + Map otherClaims = token.getOtherClaims(); + + for (String claim : tokenClaimArr) { + otherClaims.put(claim, ""); + } + } + + public static ProtocolMapperModel create( + String name, boolean accessToken, boolean idToken, boolean userInfo) { + ProtocolMapperModel mapper = new ProtocolMapperModel(); + mapper.setName(name); + mapper.setProtocolMapper(PROVIDER_ID); + mapper.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL); + Map config = new HashMap<>(); + if (accessToken) config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ACCESS_TOKEN, "true"); + if (idToken) config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ID_TOKEN, "true"); + if (userInfo) config.put(OIDCAttributeMapperHelper.INCLUDE_IN_USERINFO, "true"); + mapper.setConfig(config); + return mapper; + } + + @Override + public int getPriority() { + return 99; + } +} diff --git a/docker/keycloak/extensions-7.6/services/src/main/resources/META-INF/services/org.keycloak.protocol.ProtocolMapper b/docker/keycloak/extensions-7.6/services/src/main/resources/META-INF/services/org.keycloak.protocol.ProtocolMapper index 42ca66cc..bfc65670 100644 --- a/docker/keycloak/extensions-7.6/services/src/main/resources/META-INF/services/org.keycloak.protocol.ProtocolMapper +++ b/docker/keycloak/extensions-7.6/services/src/main/resources/META-INF/services/org.keycloak.protocol.ProtocolMapper @@ -1,2 +1,3 @@ com.github.bcgov.keycloak.protocol.oidc.mappers.IDPUserinfoMapper +com.github.bcgov.keycloak.protocol.oidc.mappers.ClaimOmitterMapper com.github.bcgov.keycloak.protocol.saml.mappers.ClientRoleListMapper diff --git a/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov-idp-stopper/login/login.ftl b/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov-idp-stopper/login/login.ftl index 945abb41..2c97f171 100755 --- a/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov-idp-stopper/login/login.ftl +++ b/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov-idp-stopper/login/login.ftl @@ -11,29 +11,29 @@ <#if idpContext[p.alias]?has_content && idpContext[p.alias]["enabled"] == "true"> diff --git a/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov/login/resources/css/styles.css b/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov/login/resources/css/styles.css index e1a0c77b..97778acf 100644 --- a/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov/login/resources/css/styles.css +++ b/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov/login/resources/css/styles.css @@ -77,17 +77,16 @@ top: 0; } -.login-pf body .login-pf-page #kc-content #kc-content-wrapper .kc-social-link { +.login-pf body .login-pf-page #kc-content #kc-content-wrapper .kc-social-link > a { display: flex; } -.login-pf body .login-pf-page #kc-content #kc-content-wrapper .kc-social-link > a { +.login-pf body .login-pf-page #kc-content #kc-content-wrapper .kc-social-link > a > .kc-social-title { width: 100%; } -.login-pf body .login-pf-page #kc-content #kc-content-wrapper .kc-social-link > span { - width: 40px; - padding: 6px; +.login-pf body .login-pf-page #kc-content #kc-content-wrapper .kc-social-link > a > .kc-social-icon { + width: 28px; } .login-pf body .login-pf-page .kc-social-links { @@ -204,7 +203,7 @@ text-decoration-line: none; border: none; border-radius: 4px; - opacity: 0.8; + background-color: rgb(0, 51, 102, 0.8); } #kc-form-buttons input:after, From 120d705ec6fd13c8aa85190d1201dc984f2a4f4c Mon Sep 17 00:00:00 2001 From: Nithin Shekar Kuruba <81444731+NithinKuruba@users.noreply.github.com> Date: Mon, 21 Nov 2022 10:41:23 -0800 Subject: [PATCH 039/118] chore: added script to migrate users from silver custom to gold custom (#230) * chore: added script to migrate users from silver to gold custom * chore: updated script to handle different idp names * chore: moved script to its own folder * chore: updated env example file * chore: added more comments * chore: refactored script code * chore: added more comments * chore: updated cmd line arg comments * chore: added env validation * chore: updated validation logic --- .tool-versions | 4 +- scripts/.gitignore | 1 + scripts/custom-realm-users/.env.example | 37 + scripts/custom-realm-users/README.md | 49 + scripts/custom-realm-users/package.json | 17 + scripts/custom-realm-users/script.js | 325 +++++ scripts/custom-realm-users/util.js | 71 ++ scripts/custom-realm-users/yarn.lock | 1494 +++++++++++++++++++++++ 8 files changed, 1996 insertions(+), 2 deletions(-) create mode 100644 scripts/custom-realm-users/.env.example create mode 100644 scripts/custom-realm-users/README.md create mode 100644 scripts/custom-realm-users/package.json create mode 100644 scripts/custom-realm-users/script.js create mode 100644 scripts/custom-realm-users/util.js create mode 100644 scripts/custom-realm-users/yarn.lock diff --git a/.tool-versions b/.tool-versions index f0fb8fd6..d720b89d 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,5 +1,5 @@ -nodejs 14.14.0 -python 3.8.6 +nodejs 16.14.0 +python 3.11.0 kubectl 1.24.2 oc 4.7.5 helm 3.8.2 diff --git a/scripts/.gitignore b/scripts/.gitignore index 33b6f374..2fcd5f5d 100644 --- a/scripts/.gitignore +++ b/scripts/.gitignore @@ -1,3 +1,4 @@ node_modules yarn-error.log .env +custom-realm-users/cleanup.js diff --git a/scripts/custom-realm-users/.env.example b/scripts/custom-realm-users/.env.example new file mode 100644 index 00000000..a3d51027 --- /dev/null +++ b/scripts/custom-realm-users/.env.example @@ -0,0 +1,37 @@ +SILVER_DEV_SSO_URL=https://dev.oidc.gov.bc.ca +SILVER_DEV_CLIENT_ID=admin-cli +SILVER_DEV_CLIENT_SECRET= +SILVER_DEV_USERNAME= +SILVER_DEV_PASSWORD= + +SILVER_TEST_SSO_URL=https://test.oidc.gov.bc.ca +SILVER_TEST_CLIENT_ID=admin-cli +SILVER_TEST_CLIENT_SECRET= +SILVER_TEST_USERNAME= +SILVER_TEST_PASSWORD= + +SILVER_PROD_SSO_URL=https://oidc.gov.bc.ca +SILVER_PROD_CLIENT_ID=admin-cli +SILVER_PROD_CLIENT_SECRET= +SILVER_PROD_USERNAME= +SILVER_PROD_PASSWORD= + +GOLD_DEV_SSO_URL=https://dev.loginproxy.gov.bc.ca +GOLD_DEV_CLIENT_ID=admin-cli +GOLD_DEV_CLIENT_SECRET= +GOLD_DEV_USERNAME= +GOLD_DEV_PASSWORD= + +GOLD_TEST_SSO_URL=https://test.loginproxy.gov.bc.ca +GOLD_TEST_CLIENT_ID=admin-cli +GOLD_TEST_CLIENT_SECRET= +GOLD_TEST_USERNAME= +GOLD_TEST_PASSWORD= + +GOLD_PROD_SSO_URL=https://loginproxy.gov.bc.ca +GOLD_PROD_CLIENT_ID=admin-cli +GOLD_PROD_CLIENT_SECRET= +GOLD_PROD_USERNAME= +GOLD_PROD_PASSWORD= + +GITHUB_PAT= diff --git a/scripts/custom-realm-users/README.md b/scripts/custom-realm-users/README.md new file mode 100644 index 00000000..c3f61351 --- /dev/null +++ b/scripts/custom-realm-users/README.md @@ -0,0 +1,49 @@ +# Script to migrate users from custom realm in silver cluster to a custom realm in gold + +## Pre-requisites + +- Request a custom realm by creating an issue [here](https://github.com/bcgov/sso-keycloak/issues/new?assignees=tzhang200%2Czsamji&labels=gold%2Ccustom&template=silver-custom-gold-custom-request.yml&title=%5BGold+Custom%5D%3A+) + +- Create an integration request [here](https://bcgov.github.io/sso-requests) to access idps of your choice + +- After your custom realm is approved, follow this [guide](https://stackoverflow.developer.gov.bc.ca/questions/864/891) to add required idps to your realm + +- Create `admin user account` or a `service account` in your silver and gold custom realms which need to have permissions to manage realm. If using service account, then navigate to `role-mapping` tab and choose client `realm-management` and assign required permissions. If using an user account then set a password and add the user to `Realm Administrator` group + +- Create `.env` from `.env.example` and update your service account or admin user credentials for connecting to your silver and gold custom realms in the script root directory + +- Optional: If the `idir` or `bceid` users in your custom realm in silver do not have respective `idir_userid` and `bceid_userid`, the users cannot be migrated. In this case do reach out to SSO team to fetch those `userids` before starting the migration + +- Optional: If you are trying to migrate `github` users, you would need a github personal access token (PAT) that has permissions to read `users profile data` + +## Steps to run the script + +### Install the dependencies + +```sh +yarn install +``` + +### Run the migration script + +#### Checks before running the script: + +- Please have your idps created in your custom realm +- Ensure `kc_idp_hint` query param is passed to the `authorization_url` of your idp + +```sh +cd ./scripts/custom-realm-users + +export SSO_SILVER_ENVIRONMENT= +export SSO_GOLD_ENVIRONMENT= +export SSO_SILVER_REALM= +export SSO_GOLD_REALM= + +node script --base-env=$SSO_SILVER_ENVIRONMENT --base-realm=$SSO_SILVER_REALM --target-env=$SSO_GOLD_ENVIRONMENT --target-realm=$SSO_GOLD_REALM +``` + +## References + +- [Setup IDPs in your custom realm](https://stackoverflow.developer.gov.bc.ca/questions/864) +- [Migrating users](https://stackoverflow.developer.gov.bc.ca/questions/915) +- [IDIR Username format](https://github.com/bcgov/sso-keycloak/discussions/138) diff --git a/scripts/custom-realm-users/package.json b/scripts/custom-realm-users/package.json new file mode 100644 index 00000000..25c1cb51 --- /dev/null +++ b/scripts/custom-realm-users/package.json @@ -0,0 +1,17 @@ +{ + "name": "custom-realm-users", + "version": "1.0.0", + "main": "index.js", + "license": "MIT", + "dependencies": { + "axios": "^1.1.3", + "dotenv": "^16.0.3", + "github-username-regex": "^1.0.0", + "jws": "^4.0.0", + "keycloak-admin": "^1.14.22", + "lodash": "^4.17.21", + "octokit": "^2.0.10", + "prompt-confirm": "^2.0.4", + "yargs": "^17.6.2" + } +} diff --git a/scripts/custom-realm-users/script.js b/scripts/custom-realm-users/script.js new file mode 100644 index 00000000..2a7fd8a9 --- /dev/null +++ b/scripts/custom-realm-users/script.js @@ -0,0 +1,325 @@ +const axios = require('axios'); +const fs = require('fs'); +const path = require('path'); +const _ = require('lodash'); +const { argv } = require('yargs'); +const Confirm = require('prompt-confirm'); +const { getKeycloakAdminClient, getGitHubClient } = require('./util'); +const githubUsernameRegex = require('github-username-regex'); +const dotenv = require('dotenv'); + +dotenv.config(); + +const { baseEnv, baseRealm, targetEnv, targetRealm, totp, idirGuidAttrKey, bceidGuidAttrKey, githubIdAttrKey } = argv; + +// key value pairs to find guid for an idp. Update if required +const idpGuidKeyMap = { + azureidir: 'idir_userid', + idir: 'idir_userid', + bceidbasic: 'bceid_userid', + bceidbusiness: 'bceid_userid', + bceidboth: 'bceid_userid', + githubbcgov: 'github_id', + githubpublic: 'github_id', +}; + +// silver parent realm idp to gold parent realm idp mapping +const silvertoGoldIdpsMap = { + _azureidir: 'azureidir', + idir: 'idir', + _bceid: 'bceidboth', + _bceidbasic: 'bceidbasic', + _bceidbusiness: 'bceidbusiness', + _bceidbasicbusiness: 'bceidboth', +}; + +const logPrefix = 'MIGRATE SILVER CUSTOM TO GOLD CUSTOM: '; + +const baseRealmAliastoIdpMap = {}; +const targetRealmAliastoIdpMap = {}; +let ghClient = ''; +const supportedEnvs = ['dev', 'test', 'prod']; + +async function main() { + if ( + !baseEnv || + !baseRealm || + !targetEnv || + !targetRealm || + !supportedEnvs.includes(baseEnv) || + !supportedEnvs.includes(targetEnv) + ) { + console.info(` + Usage: + node migrations/custom-realm-users --base-env --base-realm --target-env --context-env --target-realm [--totp ] + + Flags: + --base-env Base Keycloak environment to migrate users from. Available values: (dev, test, prod) + --base-realm Base realm of the base Keycloak environment to migrate users from + --target-env Target Keycloak environment to migrate users to. Available values: (dev, test, prod) + --target-realm Target realm of the target Keycloak environment to migrate users to + --totp Time-based One-time Password (TOTP) passed into the Keycloak auth call of the base environment; Optional + --idir-guid-attr-key User attribute key that holds AzureIDIR/IDIR Guid; optional, default to idir_userid + --bceid-guid-attr-key User attribute key that holds BCeID Guid; optional, default to bceid_userid + --github-id-attr-key User attribute key that holds GitHub Id; optional, default to github_id + `); + return; + } + + try { + // custom attribute keys that hold user guid + if (idirGuidAttrKey) { + idpGuidKeyMap['idir'] = idirGuidAttrKey; + idpGuidKeyMap['azureidir'] = idirGuidAttrKey; + } + + if (bceidGuidAttrKey) { + idpGuidKeyMap['bceidbasic'] = bceidGuidAttrKey; + idpGuidKeyMap['bceidbusiness'] = bceidGuidAttrKey; + idpGuidKeyMap['bceidboth'] = bceidGuidAttrKey; + } + + if (githubIdAttrKey) { + idpGuidKeyMap['githubbcgov'] = githubIdAttrKey; + idpGuidKeyMap['githubpublic'] = githubIdAttrKey; + } + + // fetch keycloak admin clients + const silverKcAdminClient = await getKeycloakAdminClient('silver', baseEnv, baseRealm, { totp }); + const goldKcAdminClient = await getKeycloakAdminClient('gold', targetEnv, targetRealm, { totp }); + if (!silverKcAdminClient || !goldKcAdminClient) return; + + // find all idps from base realm + const baseRealmIdps = await silverKcAdminClient.identityProviders.find({ realm: baseRealm }); + + // create a mapping between base realm idp alias and parent idp + baseRealmIdps.map((idp) => { + const urlPrefix = `https://${baseEnv === 'prod' ? '' : baseEnv + '.'}oidc.gov.bc.ca/auth/realms/`; + const urlSuffix = '/protocol/openid-connect/auth'; + // only oidc and keycloak-oidc provider types are supported + if (['oidc', 'keycloak-oidc'].includes(idp.providerId) && idp.config.authorizationUrl.startsWith(urlPrefix)) { + const parentIdp = idp.config.authorizationUrl.substring( + urlPrefix.length, + idp.config.authorizationUrl.indexOf(urlSuffix), + ); + + baseRealmAliastoIdpMap[idp.alias] = parentIdp; + } + }); + + // find all idps from target realm + const targetRealmIdps = await goldKcAdminClient.identityProviders.find(); + + // create a mapping between target realm idp alias and parent idp + targetRealmIdps.map((idp) => { + const urlPrefix = `https://${ + targetEnv === 'prod' ? '' : targetEnv + '.' + }loginproxy.gov.bc.ca/auth/realms/standard/protocol/openid-connect/auth?kc_idp_hint=`; + // only oidc and keycloak-oidc provider types are supported + if (['oidc', 'keycloak-oidc'].includes(idp.providerId) && idp.config.authorizationUrl.startsWith(urlPrefix)) { + let url = new URL(idp.config.authorizationUrl); + if (url.searchParams.get('kc_idp_hint')) { + targetRealmAliastoIdpMap[idp.alias] = url.searchParams.get('kc_idp_hint'); + } + } + }); + + // fetch github client if github users need to be migrated + if (Object.values(baseRealmAliastoIdpMap).includes('_github')) { + ghClient = getGitHubClient(); + if (!ghClient) return; + } + + // if using github then add base realm parent github idp to target realm parent github idp mapping + if (Object.values(targetRealmAliastoIdpMap).some((idp) => idp.startsWith('github'))) { + silvertoGoldIdpsMap['_github'] = Object.values(targetRealmAliastoIdpMap).find((idp) => idp.startsWith('github')); + } + + userReport = { + found: [], + 'no-idp': [], + 'invalid-idp': [], + 'no-guid': [], + 'gh-users-not-found': [], + migrated: [], + }; + const total = await silverKcAdminClient.users.count({ realm: baseRealm }); + const max = 500; + let start = 0; + for (let i = 0; i < Math.ceil(total / max); i++) { + let userList = await silverKcAdminClient.users.find({ + realm: baseRealm, + first: start, + max, + }); + + for (let x = 0; x < userList.length; x++) { + const baseUser = userList[x]; + const links = await silverKcAdminClient.users.listFederatedIdentities({ + realm: baseRealm, + id: baseUser.id, + }); + + if (links.length === 0) { + userReport['no-idp'].push(baseUser.username); + continue; + } + + const { identityProvider, userName: ghProviderUsername } = links[0]; + + if (!baseRealmAliastoIdpMap[identityProvider]) { + userReport['invalid-idp'].push(baseUser.username); + continue; + } + + const baseRealmUserParentIdp = baseRealmAliastoIdpMap[identityProvider]; + + const targetRealmUserParentIdp = silvertoGoldIdpsMap[baseRealmUserParentIdp]; + + let baseUserGuid = getBaseUserGuid(baseUser, targetRealmUserParentIdp); + + //fetch idir/bceid/github displayName from user attributes + let baseUserDisplayName = getBaseUserDisplayName(baseUser); + + //if github_id is not found in user attributes + if (!baseUserGuid && targetRealmUserParentIdp.startsWith('github')) { + // get github_id and display name from github API + try { + const ghSearchUsername = githubUsernameRegex.test(baseUser.username) + ? baseUser.username + : ghProviderUsername; + ghuser = await ghClient.rest.users.getByUsername({ username: ghSearchUsername }); + if (!ghuser.data || !ghuser.data.id) { + console.log(`${logPrefix}user ${baseUser.username} not found in GitHub API`); + userReport['gh-users-not-found'].push(baseUser.username); + continue; + } + } catch (err) { + console.error(`${logPrefix}failed migrating user ${baseUser.username} due to ${err.response.data.message}`); + continue; + } + baseUserGuid = ghuser.data.id; + baseUserDisplayName = ghuser.data.name; + } + + if (!baseUserGuid) { + userReport['no-guid'].push(baseUser.username); + continue; + } + + //idps need to exist in gold custom realm to migrate users + if (!Object.values(targetRealmAliastoIdpMap).some((idp) => idp.includes(targetRealmUserParentIdp))) { + console.error( + `${logPrefix}cannot migrate ${baseUser.username} before ${baseUserIdp} idp is added to target realm`, + ); + continue; + } + + const targetUsername = `${baseUserGuid}@${targetRealmUserParentIdp}`; + + //check if user already exists in gold custom realm + let targetUsers = await goldKcAdminClient.users.find({ + realm: targetRealm, + username: targetUsername, + exact: true, + }); + + let targetUser = {}; + + //if user does not exist already then create + if (targetUsers.length === 0) { + try { + const commonUserData = { + enabled: true, + email: baseUser.email, + firstName: baseUser.firstName, + lastName: baseUser.lastName, + realm: targetRealm, + username: targetUsername, + }; + if (targetRealmUserParentIdp.startsWith('idir') || targetRealmUserParentIdp.startsWith('azureidir')) { + targetUser = await goldKcAdminClient.users.create({ + ...commonUserData, + attributes: getUserAttributesForIdir(baseUserGuid, baseUserDisplayName, baseUser), + }); + } else if (targetRealmUserParentIdp.startsWith('bceid')) { + targetUser = await goldKcAdminClient.users.create({ + ...commonUserData, + attributes: getUserAttributesForBceid(baseUserGuid, baseUserDisplayName, baseUser), + }); + } else if (targetRealmUserParentIdp.startsWith('github')) { + targetUser = await goldKcAdminClient.users.create({ + ...commonUserData, + attributes: getUserAttributesForGithub(baseUserGuid, baseUserDisplayName, baseUser), + }); + } + //create linkage with the identity provider + await goldKcAdminClient.users.addToFederatedIdentity({ + realm: targetRealm, + id: targetUser.id, + federatedIdentityId: getObjKey(targetRealmAliastoIdpMap, targetRealmUserParentIdp), + federatedIdentity: { + userId: targetUsername, + userName: targetUsername, + identityProvider: getObjKey(targetRealmAliastoIdpMap, targetRealmUserParentIdp), + }, + }); + userReport['migrated'].push(baseUser.username); + } catch (err) { + console.log(`${logPrefix}${targetUsername} migration failed`, err.response.data); + } + } else { + userReport['found'].push(baseUser.username); + } + } + + start = start + max; + } + console.log(userReport); + } catch (err) { + console.error(err); + } +} + +main(); + +//returns user guid, please modify accordingly if required +//by default it uses idp specific user attribute to fetch the guid +const getBaseUserGuid = (baseUser, targetRealmParentIdp) => { + return _.get(baseUser, `attributes.${idpGuidKeyMap[targetRealmParentIdp]}.0`, false); +}; + +//returns user display, please modify accordingly if required +//by default it uses idp specific user attribute to fetch the displayName +const getBaseUserDisplayName = (baseUser) => { + return (baseUser?.attributes?.displayName && baseUser?.attributes?.displayName[0]) || ''; +}; + +const getObjKey = (obj, value) => { + return Object.keys(obj).find((key) => obj[key] === value); +}; + +const getUserAttributesForIdir = (guid, name, user) => { + return { + display_name: name, + idir_user_guid: guid, + idir_username: user.username, + }; +}; + +const getUserAttributesForBceid = (guid, name, user) => { + return { + display_name: name, + bceid_user_guid: guid, + bceid_business_guid: (user.attributes.bceid_business_guid && user.attributes.bceid_business_guid[0]) || '', + bceid_business_name: (user.attributes.bceid_business_name && user.attributes.bceid_business_name[0]) || '', + }; +}; + +const getUserAttributesForGithub = (guid, name, user) => { + return { + display_name: name, + github_id: guid, + github_username: user.username, + }; +}; diff --git a/scripts/custom-realm-users/util.js b/scripts/custom-realm-users/util.js new file mode 100644 index 00000000..0c3df817 --- /dev/null +++ b/scripts/custom-realm-users/util.js @@ -0,0 +1,71 @@ +const axios = require('axios'); +const jws = require('jws'); +const KcAdminClient = require('keycloak-admin').default; +const { Octokit, App } = require('octokit'); +const dotenv = require('dotenv'); + +dotenv.config(); + +const removeTrailingSlash = (url) => (url.endsWith('/') ? url.slice(0, -1) : url); + +//get admin client using client credentials or admin user account +async function getKeycloakAdminClient(ocpCluster = 'silver', environment = 'dev', kcRealm, { totp = '' } = {}) { + try { + const cluster = ocpCluster.toUpperCase(); + const env = environment.toUpperCase(); + const config = { + url: removeTrailingSlash(eval(`process.env.${cluster}_${env}_SSO_URL`)), + clientId: eval(`process.env.${cluster}_${env}_CLIENT_ID`) || 'admin-cli', + clientSecret: eval(`process.env.${cluster}_${env}_CLIENT_SECRET`), + username: eval(`process.env.${cluster}_${env}_USERNAME`), + password: eval(`process.env.${cluster}_${env}_PASSWORD`), + }; + if (!config) throw Error(`invalid env ${env}`); + + const kcAdminClient = new KcAdminClient({ + baseUrl: `${config.url}/auth`, + realmName: kcRealm, + requestConfig: { + /* Axios request config options https://github.com/axios/axios#request-config */ + timeout: 60000, + }, + }); + + let decodedToken; + + const auth = async () => { + await kcAdminClient.auth({ + grantType: config.clientSecret ? 'client_credentials' : 'password', + clientId: config.clientId, + clientSecret: config.clientSecret, + username: config.username, + password: config.password, + totp, + }); + + decodedToken = jws.decode(kcAdminClient.accessToken); + }; + + const refreshAsNeeded = async () => { + const expiresIn = decodedToken.payload.exp * 1000 - Date.now(); + console.log(expiresIn < 60 * 1000); + if (expiresIn < 60 * 1000) await auth(); + }; + + kcAdminClient.reauth = auth; + kcAdminClient.refreshAsNeeded = refreshAsNeeded; + + await auth(); + return kcAdminClient; + } catch (err) { + console.log(ocpCluster, environment, err.response.data); + return null; + } +} + +const getGitHubClient = () => { + if (!process.env.GITHUB_PAT) throw Error('Github PAT required to create github client'); + return new Octokit({ auth: process.env.GITHUB_PAT }); +}; + +module.exports = { getKeycloakAdminClient, getGitHubClient }; diff --git a/scripts/custom-realm-users/yarn.lock b/scripts/custom-realm-users/yarn.lock new file mode 100644 index 00000000..580b9680 --- /dev/null +++ b/scripts/custom-realm-users/yarn.lock @@ -0,0 +1,1494 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@octokit/app@^13.0.5": + version "13.0.11" + resolved "https://registry.yarnpkg.com/@octokit/app/-/app-13.0.11.tgz#6c61b9a614e0d913e4cb0201bb0911d5115f28c0" + integrity sha512-qlUynCN1+BNYQ6VaJOMCqDdCo/2yzPixuoFnbcUThakRV+5969Tp+LTAtsZWjjb/tUHfutaAYOnsia1EGTAzfA== + dependencies: + "@octokit/auth-app" "^4.0.0" + "@octokit/auth-unauthenticated" "^3.0.0" + "@octokit/core" "^4.0.0" + "@octokit/oauth-app" "^4.0.7" + "@octokit/plugin-paginate-rest" "^5.0.0" + "@octokit/types" "^8.0.0" + "@octokit/webhooks" "^10.0.0" + +"@octokit/auth-app@^4.0.0": + version "4.0.7" + resolved "https://registry.yarnpkg.com/@octokit/auth-app/-/auth-app-4.0.7.tgz#417c327e6a7ada1e6e9651db681146f8c12728e3" + integrity sha512-hjjVCoI/+1oLminVHJPPexguYb9FP4Q60hEHExgy1uAKMMJ5Zf8iJIeRJlIIqneTb4vt7NvUTEj4YDxBLZ1FLg== + dependencies: + "@octokit/auth-oauth-app" "^5.0.0" + "@octokit/auth-oauth-user" "^2.0.0" + "@octokit/request" "^6.0.0" + "@octokit/request-error" "^3.0.0" + "@octokit/types" "^8.0.0" + "@types/lru-cache" "^5.1.0" + deprecation "^2.3.1" + lru-cache "^6.0.0" + universal-github-app-jwt "^1.0.1" + universal-user-agent "^6.0.0" + +"@octokit/auth-oauth-app@^5.0.0": + version "5.0.4" + resolved "https://registry.yarnpkg.com/@octokit/auth-oauth-app/-/auth-oauth-app-5.0.4.tgz#ebd9a38f75381093d1a5e08e05b70b94f0918277" + integrity sha512-zlWuii5hAN50vsV6SJC+uIJ7SMhyWjQMEmKJQxkmNDlieE9LjnkZnbOjqRsfcG7VO7WTl4K8ccpo/3A7Kdpmrw== + dependencies: + "@octokit/auth-oauth-device" "^4.0.0" + "@octokit/auth-oauth-user" "^2.0.0" + "@octokit/request" "^6.0.0" + "@octokit/types" "^8.0.0" + "@types/btoa-lite" "^1.0.0" + btoa-lite "^1.0.0" + universal-user-agent "^6.0.0" + +"@octokit/auth-oauth-device@^4.0.0": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@octokit/auth-oauth-device/-/auth-oauth-device-4.0.3.tgz#00ce77233517e0d7d39e42a02652f64337d9df81" + integrity sha512-KPTx5nMntKjNZzzltO3X4T68v22rd7Cp/TcLJXQE2U8aXPcZ9LFuww9q9Q5WUNSu3jwi3lRwzfkPguRfz1R8Vg== + dependencies: + "@octokit/oauth-methods" "^2.0.0" + "@octokit/request" "^6.0.0" + "@octokit/types" "^8.0.0" + universal-user-agent "^6.0.0" + +"@octokit/auth-oauth-user@^2.0.0": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@octokit/auth-oauth-user/-/auth-oauth-user-2.0.4.tgz#88f060ec678d7d493695af8d827e115dd064e212" + integrity sha512-HrbDzTPqz6GcGSOUkR+wSeF3vEqsb9NMsmPja/qqqdiGmlk/Czkxctc3KeWYogHonp62Ml4kjz2VxKawrFsadQ== + dependencies: + "@octokit/auth-oauth-device" "^4.0.0" + "@octokit/oauth-methods" "^2.0.0" + "@octokit/request" "^6.0.0" + "@octokit/types" "^8.0.0" + btoa-lite "^1.0.0" + universal-user-agent "^6.0.0" + +"@octokit/auth-token@^3.0.0": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@octokit/auth-token/-/auth-token-3.0.2.tgz#a0fc8de149fd15876e1ac78f6525c1c5ab48435f" + integrity sha512-pq7CwIMV1kmzkFTimdwjAINCXKTajZErLB4wMLYapR2nuB/Jpr66+05wOTZMSCBXP6n4DdDWT2W19Bm17vU69Q== + dependencies: + "@octokit/types" "^8.0.0" + +"@octokit/auth-unauthenticated@^3.0.0": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@octokit/auth-unauthenticated/-/auth-unauthenticated-3.0.3.tgz#2fa91ca84a8c8cec244241c2a13732fc5a404a22" + integrity sha512-IyfLo1T5GmIC9+07hHGlD3gHtZI1Bona8PLhHXUnwcYDuZt0BhjlNJDYMoPG21C4r7v7+ZSxQHBKrGgkxpYb7A== + dependencies: + "@octokit/request-error" "^3.0.0" + "@octokit/types" "^8.0.0" + +"@octokit/core@^4.0.0", "@octokit/core@^4.0.4": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@octokit/core/-/core-4.1.0.tgz#b6b03a478f1716de92b3f4ec4fd64d05ba5a9251" + integrity sha512-Czz/59VefU+kKDy+ZfDwtOIYIkFjExOKf+HA92aiTZJ6EfWpFzYQWw0l54ji8bVmyhc+mGaLUbSUmXazG7z5OQ== + dependencies: + "@octokit/auth-token" "^3.0.0" + "@octokit/graphql" "^5.0.0" + "@octokit/request" "^6.0.0" + "@octokit/request-error" "^3.0.0" + "@octokit/types" "^8.0.0" + before-after-hook "^2.2.0" + universal-user-agent "^6.0.0" + +"@octokit/endpoint@^7.0.0": + version "7.0.3" + resolved "https://registry.yarnpkg.com/@octokit/endpoint/-/endpoint-7.0.3.tgz#0b96035673a9e3bedf8bab8f7335de424a2147ed" + integrity sha512-57gRlb28bwTsdNXq+O3JTQ7ERmBTuik9+LelgcLIVfYwf235VHbN9QNo4kXExtp/h8T423cR5iJThKtFYxC7Lw== + dependencies: + "@octokit/types" "^8.0.0" + is-plain-object "^5.0.0" + universal-user-agent "^6.0.0" + +"@octokit/graphql@^5.0.0": + version "5.0.4" + resolved "https://registry.yarnpkg.com/@octokit/graphql/-/graphql-5.0.4.tgz#519dd5c05123868276f3ae4e50ad565ed7dff8c8" + integrity sha512-amO1M5QUQgYQo09aStR/XO7KAl13xpigcy/kI8/N1PnZYSS69fgte+xA4+c2DISKqUZfsh0wwjc2FaCt99L41A== + dependencies: + "@octokit/request" "^6.0.0" + "@octokit/types" "^8.0.0" + universal-user-agent "^6.0.0" + +"@octokit/oauth-app@^4.0.6", "@octokit/oauth-app@^4.0.7": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@octokit/oauth-app/-/oauth-app-4.1.0.tgz#23782e77141015a4a3483820cd339ea62e85bb85" + integrity sha512-dGZcfmwPkS3VZ9CNnvNszp6mlnbOZh9+/uPNiK/AkvSUJGXTbUVIZTkMvAjbyIFw2WlIx++hhtrTeKNJq6uMbw== + dependencies: + "@octokit/auth-oauth-app" "^5.0.0" + "@octokit/auth-oauth-user" "^2.0.0" + "@octokit/auth-unauthenticated" "^3.0.0" + "@octokit/core" "^4.0.0" + "@octokit/oauth-authorization-url" "^5.0.0" + "@octokit/oauth-methods" "^2.0.0" + "@types/aws-lambda" "^8.10.83" + fromentries "^1.3.1" + universal-user-agent "^6.0.0" + +"@octokit/oauth-authorization-url@^5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@octokit/oauth-authorization-url/-/oauth-authorization-url-5.0.0.tgz#029626ce87f3b31addb98cd0d2355c2381a1c5a1" + integrity sha512-y1WhN+ERDZTh0qZ4SR+zotgsQUE1ysKnvBt1hvDRB2WRzYtVKQjn97HEPzoehh66Fj9LwNdlZh+p6TJatT0zzg== + +"@octokit/oauth-methods@^2.0.0": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@octokit/oauth-methods/-/oauth-methods-2.0.4.tgz#6abd9593ca7f91fe5068375a363bd70abd5516dc" + integrity sha512-RDSa6XL+5waUVrYSmOlYROtPq0+cfwppP4VaQY/iIei3xlFb0expH6YNsxNrZktcLhJWSpm9uzeom+dQrXlS3A== + dependencies: + "@octokit/oauth-authorization-url" "^5.0.0" + "@octokit/request" "^6.0.0" + "@octokit/request-error" "^3.0.0" + "@octokit/types" "^8.0.0" + btoa-lite "^1.0.0" + +"@octokit/openapi-types@^14.0.0": + version "14.0.0" + resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-14.0.0.tgz#949c5019028c93f189abbc2fb42f333290f7134a" + integrity sha512-HNWisMYlR8VCnNurDU6os2ikx0s0VyEjDYHNS/h4cgb8DeOxQ0n72HyinUtdDVxJhFy3FWLGl0DJhfEWk3P5Iw== + +"@octokit/plugin-paginate-rest@^5.0.0": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-5.0.1.tgz#93d7e74f1f69d68ba554fa6b888c2a9cf1f99a83" + integrity sha512-7A+rEkS70pH36Z6JivSlR7Zqepz3KVucEFVDnSrgHXzG7WLAzYwcHZbKdfTXHwuTHbkT1vKvz7dHl1+HNf6Qyw== + dependencies: + "@octokit/types" "^8.0.0" + +"@octokit/plugin-rest-endpoint-methods@^6.0.0": + version "6.7.0" + resolved "https://registry.yarnpkg.com/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-6.7.0.tgz#2f6f17f25b6babbc8b41d2bb0a95a8839672ce7c" + integrity sha512-orxQ0fAHA7IpYhG2flD2AygztPlGYNAdlzYz8yrD8NDgelPfOYoRPROfEyIe035PlxvbYrgkfUZIhSBKju/Cvw== + dependencies: + "@octokit/types" "^8.0.0" + deprecation "^2.3.1" + +"@octokit/plugin-retry@^4.0.3": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@octokit/plugin-retry/-/plugin-retry-4.0.3.tgz#75427ba1ad92afde07af9cb0c5197f214bb036e1" + integrity sha512-tDR+4Cs9GPPNJ7/RjTEq5ty2wqjKe1hRUV7/hch+nORow5LshlHXTT1qfYNsFPw3S9szvFFAfDEFq/xwrEpL7g== + dependencies: + "@octokit/types" "^8.0.0" + bottleneck "^2.15.3" + +"@octokit/plugin-throttling@^4.0.1": + version "4.3.2" + resolved "https://registry.yarnpkg.com/@octokit/plugin-throttling/-/plugin-throttling-4.3.2.tgz#d5eb363d5282c74b2839454a87545c5f90591a80" + integrity sha512-ZaCK599h3tzcoy0Jtdab95jgmD7X9iAk59E2E7hYKCAmnURaI4WpzwL9vckImilybUGrjY1JOWJapDs2N2D3vw== + dependencies: + "@octokit/types" "^8.0.0" + bottleneck "^2.15.3" + +"@octokit/request-error@^3.0.0": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@octokit/request-error/-/request-error-3.0.2.tgz#f74c0f163d19463b87528efe877216c41d6deb0a" + integrity sha512-WMNOFYrSaX8zXWoJg9u/pKgWPo94JXilMLb2VManNOby9EZxrQaBe/QSC4a1TzpAlpxofg2X/jMnCyZgL6y7eg== + dependencies: + "@octokit/types" "^8.0.0" + deprecation "^2.0.0" + once "^1.4.0" + +"@octokit/request@^6.0.0": + version "6.2.2" + resolved "https://registry.yarnpkg.com/@octokit/request/-/request-6.2.2.tgz#a2ba5ac22bddd5dcb3f539b618faa05115c5a255" + integrity sha512-6VDqgj0HMc2FUX2awIs+sM6OwLgwHvAi4KCK3mT2H2IKRt6oH9d0fej5LluF5mck1lRR/rFWN0YIDSYXYSylbw== + dependencies: + "@octokit/endpoint" "^7.0.0" + "@octokit/request-error" "^3.0.0" + "@octokit/types" "^8.0.0" + is-plain-object "^5.0.0" + node-fetch "^2.6.7" + universal-user-agent "^6.0.0" + +"@octokit/types@^8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@octokit/types/-/types-8.0.0.tgz#93f0b865786c4153f0f6924da067fe0bb7426a9f" + integrity sha512-65/TPpOJP1i3K4lBJMnWqPUJ6zuOtzhtagDvydAWbEXpbFYA0oMKKyLb95NFZZP0lSh/4b6K+DQlzvYQJQQePg== + dependencies: + "@octokit/openapi-types" "^14.0.0" + +"@octokit/webhooks-methods@^3.0.0": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@octokit/webhooks-methods/-/webhooks-methods-3.0.1.tgz#041ed0e5728cc076e375c372dd803ded5905535f" + integrity sha512-XftYVcBxtzC2G05kdBNn9IYLtQ+Cz6ufKkjZd0DU/qGaZEFTPzM2OabXAWG5tvL0q/I+Exio1JnRiPfetiMSEw== + +"@octokit/webhooks-types@6.6.0": + version "6.6.0" + resolved "https://registry.yarnpkg.com/@octokit/webhooks-types/-/webhooks-types-6.6.0.tgz#8f6e15aca2d42f7310ffbe8b8f1799ee206dc1df" + integrity sha512-czpEwg4UA3hb0G345BVk1zMXWwX0Qdaa4F/z7C3bP6baQ9AWY/VmCYydLU+Pi4z3aOPEJYCvt9zVhZ5CutqBKw== + +"@octokit/webhooks@^10.0.0": + version "10.3.1" + resolved "https://registry.yarnpkg.com/@octokit/webhooks/-/webhooks-10.3.1.tgz#a0d0d41873fe6f16cad89a893933a96ad3dc74a6" + integrity sha512-TSGiz9+IxP8Oh8LVFwhzLYTJ+8T/U6/fC/i1/iB39izyFzoEub3wNHlsfh8A6PUbde70w2pLr/O2ELlyQdrLgg== + dependencies: + "@octokit/request-error" "^3.0.0" + "@octokit/webhooks-methods" "^3.0.0" + "@octokit/webhooks-types" "6.6.0" + aggregate-error "^3.1.0" + +"@types/aws-lambda@^8.10.83": + version "8.10.108" + resolved "https://registry.yarnpkg.com/@types/aws-lambda/-/aws-lambda-8.10.108.tgz#ddadf0d9182f2f5e689ce5fc05b5f711fad6d115" + integrity sha512-1yh1W1WoqK3lGHy+V/Fi55zobxrDHUUsluCWdMlOXkCvtsCmHPXOG+CQ2STIL4B1g6xi6I6XzxaF8V9+zeIFLA== + +"@types/btoa-lite@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@types/btoa-lite/-/btoa-lite-1.0.0.tgz#e190a5a548e0b348adb0df9ac7fa5f1151c7cca4" + integrity sha512-wJsiX1tosQ+J5+bY5LrSahHxr2wT+uME5UDwdN1kg4frt40euqA+wzECkmq4t5QbveHiJepfdThgQrPw6KiSlg== + +"@types/jsonwebtoken@^8.3.3": + version "8.5.9" + resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-8.5.9.tgz#2c064ecb0b3128d837d2764aa0b117b0ff6e4586" + integrity sha512-272FMnFGzAVMGtu9tkr29hRL6bZj4Zs1KZNeHLnKqAvp06tAIcarTMwOh8/8bz4FmKRcMxZhZNeUAQsNLoiPhg== + dependencies: + "@types/node" "*" + +"@types/lru-cache@^5.1.0": + version "5.1.1" + resolved "https://registry.yarnpkg.com/@types/lru-cache/-/lru-cache-5.1.1.tgz#c48c2e27b65d2a153b19bfc1a317e30872e01eef" + integrity sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw== + +"@types/node@*": + version "18.11.9" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.9.tgz#02d013de7058cea16d36168ef2fc653464cfbad4" + integrity sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg== + +aggregate-error@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" + integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== + dependencies: + clean-stack "^2.0.0" + indent-string "^4.0.0" + +ansi-bgblack@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-bgblack/-/ansi-bgblack-0.1.1.tgz#a68ba5007887701b6aafbe3fa0dadfdfa8ee3ca2" + integrity sha512-tp8M/NCmSr6/skdteeo9UgJ2G1rG88X3ZVNZWXUxFw4Wh0PAGaAAWQS61sfBt/1QNcwMTY3EBKOMPujwioJLaw== + dependencies: + ansi-wrap "0.1.0" + +ansi-bgblue@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-bgblue/-/ansi-bgblue-0.1.1.tgz#67bdc04edc9b9b5278969da196dea3d75c8c3613" + integrity sha512-R8JmX2Xv3+ichUQE99oL+LvjsyK+CDWo/BtVb4QUz3hOfmf2bdEmiDot3fQcpn2WAHW3toSRdjSLm6bgtWRDlA== + dependencies: + ansi-wrap "0.1.0" + +ansi-bgcyan@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-bgcyan/-/ansi-bgcyan-0.1.1.tgz#58489425600bde9f5507068dd969ebfdb50fe768" + integrity sha512-6SByK9q2H978bmqzuzA5NPT1lRDXl3ODLz/DjC4URO5f/HqK7dnRKfoO/xQLx/makOz7zWIbRf6+Uf7bmaPSkQ== + dependencies: + ansi-wrap "0.1.0" + +ansi-bggreen@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-bggreen/-/ansi-bggreen-0.1.1.tgz#4e3191248529943f4321e96bf131d1c13816af49" + integrity sha512-8TRtOKmIPOuxjpklrkhUbqD2NnVb4WZQuIjXrT+TGKFKzl7NrL7wuNvEap3leMt2kQaCngIN1ZzazSbJNzF+Aw== + dependencies: + ansi-wrap "0.1.0" + +ansi-bgmagenta@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-bgmagenta/-/ansi-bgmagenta-0.1.1.tgz#9b28432c076eaa999418672a3efbe19391c2c7a1" + integrity sha512-UZYhobiGAlV4NiwOlKAKbkCyxOl1PPZNvdIdl/Ce5by45vwiyNdBetwHk/AjIpo1Ji9z+eE29PUBAjjfVmz5SA== + dependencies: + ansi-wrap "0.1.0" + +ansi-bgred@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-bgred/-/ansi-bgred-0.1.1.tgz#a76f92838382ba43290a6c1778424f984d6f1041" + integrity sha512-BpPHMnYmRBhcjY5knRWKjQmPDPvYU7wrgBSW34xj7JCH9+a/SEIV7+oSYVOgMFopRIadOz9Qm4zIy+mEBvUOPA== + dependencies: + ansi-wrap "0.1.0" + +ansi-bgwhite@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-bgwhite/-/ansi-bgwhite-0.1.1.tgz#6504651377a58a6ececd0331994e480258e11ba8" + integrity sha512-KIF19t+HOYOorUnHTOhZpeZ3bJsjzStBG2hSGM0WZ8YQQe4c7lj9CtwnucscJDPrNwfdz6GBF+pFkVfvHBq6uw== + dependencies: + ansi-wrap "0.1.0" + +ansi-bgyellow@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-bgyellow/-/ansi-bgyellow-0.1.1.tgz#c3fe2eb08cd476648029e6874d15a0b38f61d44f" + integrity sha512-WyRoOFSIvOeM7e7YdlSjfAV82Z6K1+VUVbygIQ7C/VGzWYuO/d30F0PG7oXeo4uSvSywR0ozixDQvtXJEorq4Q== + dependencies: + ansi-wrap "0.1.0" + +ansi-black@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-black/-/ansi-black-0.1.1.tgz#f6185e889360b2545a1ec50c0bf063fc43032453" + integrity sha512-hl7re02lWus7lFOUG6zexhoF5gssAfG5whyr/fOWK9hxNjUFLTjhbU/b4UHWOh2dbJu9/STSUv+80uWYzYkbTQ== + dependencies: + ansi-wrap "0.1.0" + +ansi-blue@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-blue/-/ansi-blue-0.1.1.tgz#15b804990e92fc9ca8c5476ce8f699777c21edbf" + integrity sha512-8Um59dYNDdQyoczlf49RgWLzYgC2H/28W3JAIyOAU/+WkMcfZmaznm+0i1ikrE0jME6Ypk9CJ9CY2+vxbPs7Fg== + dependencies: + ansi-wrap "0.1.0" + +ansi-bold@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-bold/-/ansi-bold-0.1.1.tgz#3e63950af5acc2ae2e670e6f67deb115d1a5f505" + integrity sha512-wWKwcViX1E28U6FohtWOP4sHFyArELHJ2p7+3BzbibqJiuISeskq6t7JnrLisUngMF5zMhgmXVw8Equjzz9OlA== + dependencies: + ansi-wrap "0.1.0" + +ansi-colors@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-0.2.0.tgz#72c31de2a0d9a2ccd0cac30cc9823eeb2f6434b5" + integrity sha512-ScRNUT0TovnYw6+Xo3iKh6G+VXDw2Ds7ZRnMIuKBgHY02DgvT2T2K22/tc/916Fi0W/5Z1RzDaHQwnp75hqdbA== + dependencies: + ansi-bgblack "^0.1.1" + ansi-bgblue "^0.1.1" + ansi-bgcyan "^0.1.1" + ansi-bggreen "^0.1.1" + ansi-bgmagenta "^0.1.1" + ansi-bgred "^0.1.1" + ansi-bgwhite "^0.1.1" + ansi-bgyellow "^0.1.1" + ansi-black "^0.1.1" + ansi-blue "^0.1.1" + ansi-bold "^0.1.1" + ansi-cyan "^0.1.1" + ansi-dim "^0.1.1" + ansi-gray "^0.1.1" + ansi-green "^0.1.1" + ansi-grey "^0.1.1" + ansi-hidden "^0.1.1" + ansi-inverse "^0.1.1" + ansi-italic "^0.1.1" + ansi-magenta "^0.1.1" + ansi-red "^0.1.1" + ansi-reset "^0.1.1" + ansi-strikethrough "^0.1.1" + ansi-underline "^0.1.1" + ansi-white "^0.1.1" + ansi-yellow "^0.1.1" + lazy-cache "^2.0.1" + +ansi-cyan@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-cyan/-/ansi-cyan-0.1.1.tgz#538ae528af8982f28ae30d86f2f17456d2609873" + integrity sha512-eCjan3AVo/SxZ0/MyIYRtkpxIu/H3xZN7URr1vXVrISxeyz8fUFz0FJziamK4sS8I+t35y4rHg1b2PklyBe/7A== + dependencies: + ansi-wrap "0.1.0" + +ansi-dim@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-dim/-/ansi-dim-0.1.1.tgz#40de4c603aa8086d8e7a86b8ff998d5c36eefd6c" + integrity sha512-zAfb1fokXsq4BoZBkL0eK+6MfFctbzX3R4UMcoWrL1n2WHewFKentTvOZv2P11u6P4NtW/V47hVjaN7fJiefOg== + dependencies: + ansi-wrap "0.1.0" + +ansi-gray@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-gray/-/ansi-gray-0.1.1.tgz#2962cf54ec9792c48510a3deb524436861ef7251" + integrity sha512-HrgGIZUl8h2EHuZaU9hTR/cU5nhKxpVE1V6kdGsQ8e4zirElJ5fvtfc8N7Q1oq1aatO275i8pUFUCpNWCAnVWw== + dependencies: + ansi-wrap "0.1.0" + +ansi-green@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-green/-/ansi-green-0.1.1.tgz#8a5d9a979e458d57c40e33580b37390b8e10d0f7" + integrity sha512-WJ70OI4jCaMy52vGa/ypFSKFb/TrYNPaQ2xco5nUwE0C5H8piume/uAZNNdXXiMQ6DbRmiE7l8oNBHu05ZKkrw== + dependencies: + ansi-wrap "0.1.0" + +ansi-grey@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-grey/-/ansi-grey-0.1.1.tgz#59d98b6ac2ba19f8a51798e9853fba78339a33c1" + integrity sha512-+J1nM4lC+whSvf3T4jsp1KR+C63lypb+VkkwtLQMc1Dlt+nOvdZpFT0wwFTYoSlSwCcLUAaOpHF6kPkYpSa24A== + dependencies: + ansi-wrap "0.1.0" + +ansi-hidden@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-hidden/-/ansi-hidden-0.1.1.tgz#ed6a4c498d2bb7cbb289dbf2a8d1dcc8567fae0f" + integrity sha512-8gB1bo9ym9qZ/Obvrse1flRsfp2RE+40B23DhQcKxY+GSeaOJblLnzBOxzvmLTWbi5jNON3as7wd9rC0fNK73Q== + dependencies: + ansi-wrap "0.1.0" + +ansi-inverse@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-inverse/-/ansi-inverse-0.1.1.tgz#b6af45826fe826bfb528a6c79885794355ccd269" + integrity sha512-Kq8Z0dBRhQhDMN/Rso1Nu9niwiTsRkJncfJZXiyj7ApbfJrGrrubHXqXI37feJZkYcIx6SlTBdNCeK0OQ6X6ag== + dependencies: + ansi-wrap "0.1.0" + +ansi-italic@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-italic/-/ansi-italic-0.1.1.tgz#104743463f625c142a036739cf85eda688986f23" + integrity sha512-jreCxifSAqbaBvcibeQxcwhQDbEj7gF69XnpA6x83qbECEBaRBD1epqskrmov1z4B+zzQuEdwbWxgzvhKa+PkA== + dependencies: + ansi-wrap "0.1.0" + +ansi-magenta@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-magenta/-/ansi-magenta-0.1.1.tgz#063b5ba16fb3f23e1cfda2b07c0a89de11e430ae" + integrity sha512-A1Giu+HRwyWuiXKyXPw2AhG1yWZjNHWO+5mpt+P+VWYkmGRpLPry0O5gmlJQEvpjNpl4RjFV7DJQ4iozWOmkbQ== + dependencies: + ansi-wrap "0.1.0" + +ansi-red@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-red/-/ansi-red-0.1.1.tgz#8c638f9d1080800a353c9c28c8a81ca4705d946c" + integrity sha512-ewaIr5y+9CUTGFwZfpECUbFlGcC0GCw1oqR9RI6h1gQCd9Aj2GxSckCnPsVJnmfMZbwFYE+leZGASgkWl06Jow== + dependencies: + ansi-wrap "0.1.0" + +ansi-regex@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.1.tgz#123d6479e92ad45ad897d4054e3c7ca7db4944e1" + integrity sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw== + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-reset@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-reset/-/ansi-reset-0.1.1.tgz#e7e71292c3c7ddcd4d62ef4a6c7c05980911c3b7" + integrity sha512-n+D0qD3B+h/lP0dSwXX1SZMoXufdUVotLMwUuvXa50LtBAh3f+WV8b5nFMfLL/hgoPBUt+rG/pqqzF8krlZKcw== + dependencies: + ansi-wrap "0.1.0" + +ansi-strikethrough@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-strikethrough/-/ansi-strikethrough-0.1.1.tgz#d84877140b2cff07d1c93ebce69904f68885e568" + integrity sha512-gWkLPDvHH2pC9YEKqp8dIl0mg3sRglMPvioqGDIOXiwxjxUwIJ1gF86E2o4R5yLNh8IAkwHbaMtASkJfkQ2hIA== + dependencies: + ansi-wrap "0.1.0" + +ansi-styles@^4.0.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +ansi-underline@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-underline/-/ansi-underline-0.1.1.tgz#dfc920f4c97b5977ea162df8ffb988308aaa71a4" + integrity sha512-D+Bzwio/0/a0Fu5vJzrIT6bFk43TW46vXfSvzysOTEHcXOAUJTVMHWDbELIzGU4AVxVw2rCTb7YyWS4my2cSKQ== + dependencies: + ansi-wrap "0.1.0" + +ansi-white@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-white/-/ansi-white-0.1.1.tgz#9c77b7c193c5ee992e6011d36ec4c921b4578944" + integrity sha512-DJHaF2SRzBb9wZBgqIJNjjTa7JUJTO98sHeTS1sDopyKKRopL1KpaJ20R6W2f/ZGras8bYyIZDtNwYOVXNgNFg== + dependencies: + ansi-wrap "0.1.0" + +ansi-wrap@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf" + integrity sha512-ZyznvL8k/FZeQHr2T6LzcJ/+vBApDnMNZvfVFy3At0knswWd6rJ3/0Hhmpu8oqa6C92npmozs890sX9Dl6q+Qw== + +ansi-yellow@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-yellow/-/ansi-yellow-0.1.1.tgz#cb9356f2f46c732f0e3199e6102955a77da83c1d" + integrity sha512-6E3D4BQLXHLl3c/NwirWVZ+BCkMq2qsYxdeAGGOijKrx09FaqU+HktFL6QwAwNvgJiMLnv6AQ2C1gFZx0h1CBg== + dependencies: + ansi-wrap "0.1.0" + +arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== + +arr-swap@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arr-swap/-/arr-swap-1.0.1.tgz#147590ed65fc815bc07fef0997c2e5823d643534" + integrity sha512-SxBKd/By8+AaREcv/ZhFqmapfpqK4kyaQkUHwmJjlczI5ZtuuT5gofKHlCrSJ4oR7zXezFhv+7zsnLEdg9uGgQ== + dependencies: + is-number "^3.0.0" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== + +axios@^0.21.0: + version "0.21.4" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575" + integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg== + dependencies: + follow-redirects "^1.14.0" + +axios@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.1.3.tgz#8274250dada2edf53814ed7db644b9c2866c1e35" + integrity sha512-00tXVRwKx/FZr/IDVFt4C+f9FYairX517WoGCL6dpOntqLkZofjhu43F/Xl44UOpqa+9sLFDrG/XAnFsUYgkDA== + dependencies: + follow-redirects "^1.15.0" + form-data "^4.0.0" + proxy-from-env "^1.1.0" + +base64-js@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" + integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== + +before-after-hook@^2.2.0: + version "2.2.3" + resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.2.3.tgz#c51e809c81a4e354084422b9b26bad88249c517c" + integrity sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ== + +bottleneck@^2.15.3: + version "2.19.5" + resolved "https://registry.yarnpkg.com/bottleneck/-/bottleneck-2.19.5.tgz#5df0b90f59fd47656ebe63c78a98419205cadd91" + integrity sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw== + +btoa-lite@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/btoa-lite/-/btoa-lite-1.0.0.tgz#337766da15801210fdd956c22e9c6891ab9d0337" + integrity sha512-gvW7InbIyF8AicrqWoptdW08pUxuhq8BEgowNajy9RhiE86fmGAGl+bLKo6oB8QP0CkqHLowfN0oJdKC/J6LbA== + +buffer-equal-constant-time@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" + integrity sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA== + +camelize@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.1.tgz#89b7e16884056331a35d6b5ad064332c91daa6c3" + integrity sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ== + +choices-separator@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/choices-separator/-/choices-separator-2.0.0.tgz#92fd1763182d79033f5c5c51d0ba352e5567c696" + integrity sha512-BCKlzRcP2V6X+85TSKn09oGZkO2zK2zytGyZeHvM2s+kv/ydAzJtsc+rZqYRWNlojIBfkOnPxgKXrBefTFZbTQ== + dependencies: + ansi-dim "^0.1.1" + debug "^2.6.6" + strip-color "^0.1.0" + +clean-stack@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" + integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== + +cliui@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" + integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.1" + wrap-ansi "^7.0.0" + +clone-deep@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-1.0.0.tgz#b2f354444b5d4a0ce58faca337ef34da2b14a6c7" + integrity sha512-hmJRX8x1QOJVV+GUjOBzi6iauhPqc9hIF6xitWRBbiPZOBb6vGo/mDRIK9P74RTKSQK7AE8B0DDWY/vpRrPmQw== + dependencies: + for-own "^1.0.0" + is-plain-object "^2.0.4" + kind-of "^5.0.0" + shallow-clone "^1.0.0" + +clone-deep@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" + integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== + dependencies: + is-plain-object "^2.0.4" + kind-of "^6.0.2" + shallow-clone "^3.0.0" + +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw== + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +combined-stream@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +component-emitter@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + integrity sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw== + +debug@^2.6.6, debug@^2.6.8: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@^3.0.1: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og== + +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA== + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA== + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== + +deprecation@^2.0.0, deprecation@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919" + integrity sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ== + +dotenv@^16.0.3: + version "16.0.3" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.3.tgz#115aec42bac5053db3c456db30cc243a5a836a07" + integrity sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ== + +ecdsa-sig-formatter@1.0.11: + version "1.0.11" + resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf" + integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ== + dependencies: + safe-buffer "^5.0.1" + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +error-symbol@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/error-symbol/-/error-symbol-0.1.0.tgz#0a4dae37d600d15a29ba453d8ef920f1844333f6" + integrity sha512-VyjaKxUmeDX/m2lxm/aknsJ1GWDWUO2Ze2Ad8S1Pb9dykAm9TjSKp5CjrNyltYqZ5W/PO6TInAmO2/BfwMyT1g== + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug== + dependencies: + is-extendable "^0.1.0" + +filter-obj@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/filter-obj/-/filter-obj-1.1.0.tgz#9b311112bc6c6127a16e016c6c5d7f19e0805c5b" + integrity sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ== + +follow-redirects@^1.14.0, follow-redirects@^1.15.0: + version "1.15.2" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" + integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== + +for-in@^0.1.3: + version "0.1.8" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-0.1.8.tgz#d8773908e31256109952b1fdb9b3fa867d2775e1" + integrity sha512-F0to7vbBSHP8E3l6dCjxNOLuSFAACIxFy3UehTUlG7svlXi37HHsDkyVcHo0Pq8QwrE+pXvWSVX3ZT1T9wAZ9g== + +for-in@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ== + +for-own@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-1.0.0.tgz#c63332f415cedc4b04dbfe70cf836494c53cb44b" + integrity sha512-0OABksIGrxKK8K4kynWkQ7y1zounQxP+CWnyclVwj81KW3vlLlGUx57DKGcP/LH216GzqnstnPocF16Nxs0Ycg== + dependencies: + for-in "^1.0.1" + +form-data@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + +fromentries@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/fromentries/-/fromentries-1.3.2.tgz#e4bca6808816bf8f93b52750f1127f5a6fd86e3a" + integrity sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg== + +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +github-username-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/github-username-regex/-/github-username-regex-1.0.0.tgz#17356840032f904efe8d93351c7aa7e01eff21b9" + integrity sha512-EqDVkN0/5MQyDPOSDLInVRRXdeISRfcN1UW/1FUqD2knV1HHw8DndMB3UPNn5lO51DvRnjzbLXwWqNNV86PLOw== + +indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== + +info-symbol@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/info-symbol/-/info-symbol-0.1.0.tgz#27841d72867ddb4242cd612d79c10633881c6a78" + integrity sha512-qkc9wjLDQ+dYYZnY5uJXGNNHyZ0UOMDUnhvy0SEZGVVYmQ5s4i8cPAin2MbU6OxJgi8dfj/AnwqPx0CJE6+Lsw== + +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + integrity sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A== + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== + dependencies: + kind-of "^6.0.0" + +is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== + +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + integrity sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg== + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== + dependencies: + kind-of "^6.0.0" + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw== + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w== + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg== + dependencies: + kind-of "^3.0.2" + +is-number@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-6.0.0.tgz#e6d15ad31fc262887cccf217ae5f9316f81b1995" + integrity sha512-Wu1VHeILBK8KAWJUAiSZQX94GmOE45Rg6/538fKwiloUu21KncEkYGPqob2oSZ5mUT73vLGrHQjKw3KMPwfDzg== + +is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-plain-object@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" + integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== + +is-windows@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== + +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== + +js-sha256@0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/js-sha256/-/js-sha256-0.9.0.tgz#0b89ac166583e91ef9123644bd3c5334ce9d0966" + integrity sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA== + +jsonwebtoken@^8.5.1: + version "8.5.1" + resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d" + integrity sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w== + dependencies: + jws "^3.2.2" + lodash.includes "^4.3.0" + lodash.isboolean "^3.0.3" + lodash.isinteger "^4.0.4" + lodash.isnumber "^3.0.3" + lodash.isplainobject "^4.0.6" + lodash.isstring "^4.0.1" + lodash.once "^4.0.0" + ms "^2.1.1" + semver "^5.6.0" + +jwa@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a" + integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA== + dependencies: + buffer-equal-constant-time "1.0.1" + ecdsa-sig-formatter "1.0.11" + safe-buffer "^5.0.1" + +jwa@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/jwa/-/jwa-2.0.0.tgz#a7e9c3f29dae94027ebcaf49975c9345593410fc" + integrity sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA== + dependencies: + buffer-equal-constant-time "1.0.1" + ecdsa-sig-formatter "1.0.11" + safe-buffer "^5.0.1" + +jws@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304" + integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA== + dependencies: + jwa "^1.4.1" + safe-buffer "^5.0.1" + +jws@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jws/-/jws-4.0.0.tgz#2d4e8cf6a318ffaa12615e9dec7e86e6c97310f4" + integrity sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg== + dependencies: + jwa "^2.0.0" + safe-buffer "^5.0.1" + +keycloak-admin@^1.14.22: + version "1.14.22" + resolved "https://registry.yarnpkg.com/keycloak-admin/-/keycloak-admin-1.14.22.tgz#dea8c5c662a8e0983128a6676c0d8382a6cbd1a0" + integrity sha512-5OHoNKy0w2Z2ek6mZvSpWoJtKW78Tr2fC4VdkOMcj1QmlXqPhZ6Ltl8ar3Wl2JYecS72hMT0Qd4yrILRuDwW2Q== + dependencies: + axios "^0.21.0" + camelize "^1.0.0" + keycloak-js "^11.0.3" + lodash "^4.17.21" + query-string "^6.13.7" + url-join "^4.0.0" + url-template "^2.0.8" + +keycloak-js@^11.0.3: + version "11.0.3" + resolved "https://registry.yarnpkg.com/keycloak-js/-/keycloak-js-11.0.3.tgz#5f22f22662211e2bfa5327d3d2eb83020a5baa23" + integrity sha512-e2OVyCiru25UhJz3aPj5irf//+vJzvAhHdcsCIWAcvF8Te22iUoZqEdNFji8D3zNzDehX4VpuIJwQOYCj6rqTA== + dependencies: + base64-js "1.3.1" + js-sha256 "0.9.0" + +kind-of@^3.0.2, kind-of@^3.0.3: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ== + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0, kind-of@^5.0.2: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +koalas@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/koalas/-/koalas-1.0.2.tgz#318433f074235db78fae5661a02a8ca53ee295cd" + integrity sha512-RYhBbYaTTTHId3l6fnMZc3eGQNW6FVCqMG6AMwA5I1Mafr6AflaXeoi6x3xQuATRotGYRLk6+1ELZH4dstFNOA== + +lazy-cache@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-2.0.2.tgz#b9190a4f913354694840859f8a8f7084d8822264" + integrity sha512-7vp2Acd2+Kz4XkzxGxaB1FWOi8KjWIWsgdfD5MCb86DWvlLqhRPM+d6Pro3iNEL5VT9mstz5hKAlcd+QR6H3aA== + dependencies: + set-getter "^0.1.0" + +lodash.includes@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" + integrity sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w== + +lodash.isboolean@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" + integrity sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg== + +lodash.isinteger@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" + integrity sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA== + +lodash.isnumber@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" + integrity sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw== + +lodash.isplainobject@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" + integrity sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA== + +lodash.isstring@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" + integrity sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw== + +lodash.once@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" + integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg== + +lodash@^4.17.21: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +log-ok@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/log-ok/-/log-ok-0.1.1.tgz#bea3dd36acd0b8a7240d78736b5b97c65444a334" + integrity sha512-cc8VrkS6C+9TFuYAwuHpshrcrGRAv7d0tUJ0GdM72ZBlKXtlgjUZF84O+OhQUdiVHoF7U/nVxwpjOdwUJ8d3Vg== + dependencies: + ansi-green "^0.1.1" + success-symbol "^0.1.0" + +log-utils@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/log-utils/-/log-utils-0.2.1.tgz#a4c217a0dd9a50515d9b920206091ab3d4e031cf" + integrity sha512-udyegKoMz9eGfpKAX//Khy7sVAZ8b1F7oLDnepZv/1/y8xTvsyPgqQrM94eG8V0vcc2BieYI2kVW4+aa6m+8Qw== + dependencies: + ansi-colors "^0.2.0" + error-symbol "^0.1.0" + info-symbol "^0.1.0" + log-ok "^0.1.1" + success-symbol "^0.1.0" + time-stamp "^1.0.1" + warning-symbol "^0.1.0" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w== + dependencies: + object-visit "^1.0.0" + +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.12: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +mixin-object@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/mixin-object/-/mixin-object-2.0.1.tgz#4fb949441dab182540f1fe035ba60e1947a5e57e" + integrity sha512-ALGF1Jt9ouehcaXaHhn6t1yGWRqGaHkPFndtFVHfZXOvkIZ/yoGaSi0AHVTafb3ZBGg4dr/bDwnaEKqCXzchMA== + dependencies: + for-in "^0.1.3" + is-extendable "^0.1.1" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + +ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +mute-stream@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" + integrity sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ== + +node-fetch@^2.6.7: + version "2.6.7" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" + integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== + dependencies: + whatwg-url "^5.0.0" + +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ== + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA== + dependencies: + isobject "^3.0.0" + +octokit@^2.0.10: + version "2.0.10" + resolved "https://registry.yarnpkg.com/octokit/-/octokit-2.0.10.tgz#e3b991b34fba733ced82b4ddb2444aeeb7da0d2a" + integrity sha512-sI15RZVaV9iyqLLEky4i++tMM48Fo9a80zrpOXMdAtbomznBLDi/moi9mAjJg7Ii+EaSEyaWOVIh3M/Vk/a5mw== + dependencies: + "@octokit/app" "^13.0.5" + "@octokit/core" "^4.0.4" + "@octokit/oauth-app" "^4.0.6" + "@octokit/plugin-paginate-rest" "^5.0.0" + "@octokit/plugin-rest-endpoint-methods" "^6.0.0" + "@octokit/plugin-retry" "^4.0.3" + "@octokit/plugin-throttling" "^4.0.1" + "@octokit/types" "^8.0.0" + +once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +pointer-symbol@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/pointer-symbol/-/pointer-symbol-1.0.0.tgz#60f9110204ea7a929b62644a21315543cbb3d447" + integrity sha512-pozTTFO3kG9HQWXCSTJkCgq4fBF8lUQf+5bLddTEW6v4zdjQhcBVfLmKzABEMJMA7s8jhzi0sgANIwdrf4kq+A== + +prompt-actions@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/prompt-actions/-/prompt-actions-3.0.2.tgz#537eee52241c940379f354a06eae8528e44ceeba" + integrity sha512-dhz2Fl7vK+LPpmnQ/S/eSut4BnH4NZDLyddHKi5uTU/2PDn3grEMGkgsll16V5RpVUh/yxdiam0xsM0RD4xvtg== + dependencies: + debug "^2.6.8" + +prompt-base@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/prompt-base/-/prompt-base-4.1.0.tgz#7b88e4c01b096c83d2f4e501a7e85f0d369ecd1f" + integrity sha512-svGzgLUKZoqomz9SGMkf1hBG8Wl3K7JGuRCXc/Pv7xw8239hhaTBXrmjt7EXA9P/QZzdyT8uNWt9F/iJTXq75g== + dependencies: + component-emitter "^1.2.1" + debug "^3.0.1" + koalas "^1.0.2" + log-utils "^0.2.1" + prompt-actions "^3.0.2" + prompt-question "^5.0.1" + readline-ui "^2.2.3" + readline-utils "^2.2.3" + static-extend "^0.1.2" + +prompt-choices@^4.0.5: + version "4.1.0" + resolved "https://registry.yarnpkg.com/prompt-choices/-/prompt-choices-4.1.0.tgz#6094202c4e55d0762e49c1e53735727e53fd484f" + integrity sha512-ZNYLv6rW9z9n0WdwCkEuS+w5nUAGzRgtRt6GQ5aFNFz6MIcU7nHFlHOwZtzy7RQBk80KzUGPSRQphvMiQzB8pg== + dependencies: + arr-flatten "^1.1.0" + arr-swap "^1.0.1" + choices-separator "^2.0.0" + clone-deep "^4.0.0" + collection-visit "^1.0.0" + define-property "^2.0.2" + is-number "^6.0.0" + kind-of "^6.0.2" + koalas "^1.0.2" + log-utils "^0.2.1" + pointer-symbol "^1.0.0" + radio-symbol "^2.0.0" + set-value "^3.0.0" + strip-color "^0.1.0" + terminal-paginator "^2.0.2" + toggle-array "^1.0.1" + +prompt-confirm@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/prompt-confirm/-/prompt-confirm-2.0.4.tgz#42c06907333e876f2ae8867281e0b9521a4796ca" + integrity sha512-X5lzbC8/kMNHdPOqQPfMKpH4VV2f7v2OTRJoN69ZYBirSwTeQaf9ZhmzPEO9ybMA0YV2Pha5MV27u2/U4ahWfg== + dependencies: + ansi-cyan "^0.1.1" + prompt-base "^4.0.1" + +prompt-question@^5.0.1: + version "5.0.2" + resolved "https://registry.yarnpkg.com/prompt-question/-/prompt-question-5.0.2.tgz#81a479f38f0bafecc758e5d6f7bc586e599610b3" + integrity sha512-wreaLbbu8f5+7zXds199uiT11Ojp59Z4iBi6hONlSLtsKGTvL2UY8VglcxQ3t/X4qWIxsNCg6aT4O8keO65v6Q== + dependencies: + clone-deep "^1.0.0" + debug "^3.0.1" + define-property "^1.0.0" + isobject "^3.0.1" + kind-of "^5.0.2" + koalas "^1.0.2" + prompt-choices "^4.0.5" + +proxy-from-env@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" + integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== + +query-string@^6.13.7: + version "6.14.1" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.14.1.tgz#7ac2dca46da7f309449ba0f86b1fd28255b0c86a" + integrity sha512-XDxAeVmpfu1/6IjyT/gXHOl+S0vQ9owggJ30hhWKdHAsNPOcasn5o9BW0eejZqL2e4vMjhAxoW3jVHcD6mbcYw== + dependencies: + decode-uri-component "^0.2.0" + filter-obj "^1.1.0" + split-on-first "^1.0.0" + strict-uri-encode "^2.0.0" + +radio-symbol@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/radio-symbol/-/radio-symbol-2.0.0.tgz#7aa9bfc50485636d52dd76d6a8e631b290799ae1" + integrity sha512-fpuWhwGD4XG1BfUWKXhCqdguCXzGi/DDb6RzmAGZo9R75enjlx0l+ZhHF93KNG7iNpT0Vi7wEqbf8ZErbe+JtQ== + dependencies: + ansi-gray "^0.1.1" + ansi-green "^0.1.1" + is-windows "^1.0.1" + +readline-ui@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/readline-ui/-/readline-ui-2.2.3.tgz#9e873a7668bbd8ca8a5573ce810a6bafb70a5089" + integrity sha512-ix7jz0PxqQqcIuq3yQTHv1TOhlD2IHO74aNO+lSuXsRYm1d+pdyup1yF3zKyLK1wWZrVNGjkzw5tUegO2IDy+A== + dependencies: + component-emitter "^1.2.1" + debug "^2.6.8" + readline-utils "^2.2.1" + string-width "^2.0.0" + +readline-utils@^2.2.1, readline-utils@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/readline-utils/-/readline-utils-2.2.3.tgz#6f847d6b8f1915c391b581c367cd47873862351a" + integrity sha512-cjFo7R7e7AaFOz2JLQ4EgsHh4+l7mw29Eu3DAEPgGeWbYQFKqyxWsL61/McC6b2oJAvn14Ea8eUms9o8ZFC1iQ== + dependencies: + arr-flatten "^1.1.0" + extend-shallow "^2.0.1" + is-buffer "^1.1.5" + is-number "^3.0.0" + is-windows "^1.0.1" + koalas "^1.0.2" + mute-stream "0.0.7" + strip-color "^0.1.0" + window-size "^1.1.0" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + +safe-buffer@^5.0.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +semver@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +set-getter@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/set-getter/-/set-getter-0.1.1.tgz#a3110e1b461d31a9cfc8c5c9ee2e9737ad447102" + integrity sha512-9sVWOy+gthr+0G9DzqqLaYNA7+5OKkSmcqjL9cBpDEaZrr3ShQlyX2cZ/O/ozE41oxn/Tt0LGEM/w4Rub3A3gw== + dependencies: + to-object-path "^0.3.0" + +set-value@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-3.0.3.tgz#178e190d29cec6c086167222177b2fcb92f7ad56" + integrity sha512-Xsn/XSatoVOGBbp5hs3UylFDs5Bi9i+ArpVJKdHPniZHoEgRniXTqHWrWrGQ0PbEClVT6WtfnBwR8CAHC9sveg== + dependencies: + is-plain-object "^2.0.4" + +shallow-clone@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-1.0.0.tgz#4480cd06e882ef68b2ad88a3ea54832e2c48b571" + integrity sha512-oeXreoKR/SyNJtRJMAKPDSvd28OqEwG4eR/xc856cRGBII7gX9lvAqDxusPm0846z/w/hWYjI1NpKwJ00NHzRA== + dependencies: + is-extendable "^0.1.1" + kind-of "^5.0.0" + mixin-object "^2.0.1" + +shallow-clone@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" + integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== + dependencies: + kind-of "^6.0.2" + +split-on-first@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/split-on-first/-/split-on-first-1.1.0.tgz#f610afeee3b12bce1d0c30425e76398b78249a5f" + integrity sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw== + +static-extend@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g== + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + +strict-uri-encode@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546" + integrity sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ== + +string-width@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow== + dependencies: + ansi-regex "^3.0.0" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-color@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/strip-color/-/strip-color-0.1.0.tgz#106f65d3d3e6a2d9401cac0eb0ce8b8a702b4f7b" + integrity sha512-p9LsUieSjWNNAxVCXLeilaDlmuUOrDS5/dF9znM1nZc7EGX5+zEFC0bEevsNIaldjlks+2jns5Siz6F9iK6jwA== + +success-symbol@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/success-symbol/-/success-symbol-0.1.0.tgz#24022e486f3bf1cdca094283b769c472d3b72897" + integrity sha512-7S6uOTxPklNGxOSbDIg4KlVLBQw1UiGVyfCUYgYxrZUKRblUkmGj7r8xlfQoFudvqLv6Ap5gd76/IIFfI9JG2A== + +terminal-paginator@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/terminal-paginator/-/terminal-paginator-2.0.2.tgz#967e66056f28fe8f55ba7c1eebfb7c3ef371c1d3" + integrity sha512-IZMT5ECF9p4s+sNCV8uvZSW9E1+9zy9Ji9xz2oee8Jfo7hUFpauyjxkhfRcIH6Lu3Wdepv5D1kVRc8Hx74/LfQ== + dependencies: + debug "^2.6.6" + extend-shallow "^2.0.1" + log-utils "^0.2.1" + +time-stamp@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3" + integrity sha512-gLCeArryy2yNTRzTGKbZbloctj64jkZ57hj5zdraXue6aFgd6PmvVtEyiUU+hvU0v7q08oVv8r8ev0tRo6bvgw== + +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg== + dependencies: + kind-of "^3.0.2" + +toggle-array@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toggle-array/-/toggle-array-1.0.1.tgz#cbf5840792bd5097f33117ae824c932affe87d58" + integrity sha512-TZXgboKpD5Iu0Goi8hRXuJpE06Pbo+bies4I4jnTBhlRRgyen9c37nMylnquK/ZPKXXOeh1mJ14p9QdKp+9v7A== + dependencies: + isobject "^3.0.0" + +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== + +universal-github-app-jwt@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/universal-github-app-jwt/-/universal-github-app-jwt-1.1.0.tgz#0abaa876101cdf1d3e4c546be2768841c0c1b514" + integrity sha512-3b+ocAjjz4JTyqaOT+NNBd5BtTuvJTxWElIoeHSVelUV9J3Jp7avmQTdLKCaoqi/5Ox2o/q+VK19TJ233rVXVQ== + dependencies: + "@types/jsonwebtoken" "^8.3.3" + jsonwebtoken "^8.5.1" + +universal-user-agent@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-6.0.0.tgz#3381f8503b251c0d9cd21bc1de939ec9df5480ee" + integrity sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w== + +url-join@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/url-join/-/url-join-4.0.1.tgz#b642e21a2646808ffa178c4c5fda39844e12cde7" + integrity sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA== + +url-template@^2.0.8: + version "2.0.8" + resolved "https://registry.yarnpkg.com/url-template/-/url-template-2.0.8.tgz#fc565a3cccbff7730c775f5641f9555791439f21" + integrity sha512-XdVKMF4SJ0nP/O7XIPB0JwAEuT9lDIYnNsK8yGVe43y0AWoKeJNdv3ZNWh7ksJ6KqQFjOO6ox/VEitLnaVNufw== + +warning-symbol@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/warning-symbol/-/warning-symbol-0.1.0.tgz#bb31dd11b7a0f9d67ab2ed95f457b65825bbad21" + integrity sha512-1S0lwbHo3kNUKA4VomBAhqn4DPjQkIKSdbOin5K7EFUQNwyIKx+wZMGXKI53RUjla8V2B8ouQduUlgtx8LoSMw== + +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== + +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + +window-size@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/window-size/-/window-size-1.1.1.tgz#9858586580ada78ab26ecd6978a6e03115c1af20" + integrity sha512-5D/9vujkmVQ7pSmc0SCBmHXbkv6eaHwXEx65MywhmUMsI8sGqJ972APq1lotfcwMKPFLuCFfL8xGHLIp7jaBmA== + dependencies: + define-property "^1.0.0" + is-number "^3.0.0" + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yargs-parser@^21.1.1: + version "21.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" + integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== + +yargs@^17.6.2: + version "17.6.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.6.2.tgz#2e23f2944e976339a1ee00f18c77fedee8332541" + integrity sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw== + dependencies: + cliui "^8.0.1" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.3" + y18n "^5.0.5" + yargs-parser "^21.1.1" From 4c95e91037d6a19caaff2309de627279f8125234 Mon Sep 17 00:00:00 2001 From: Junmin Ahn Date: Mon, 21 Nov 2022 11:59:45 -0800 Subject: [PATCH 040/118] chore: bump sandbox keycloak image version --- helm/keycloak/values-b861c7-test-4.yaml | 2 +- helm/keycloak/values-b861c7-test-5.yaml | 2 +- helm/keycloak/values-b861c7-test-6.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/helm/keycloak/values-b861c7-test-4.yaml b/helm/keycloak/values-b861c7-test-4.yaml index 5a7edf02..029e2c6a 100644 --- a/helm/keycloak/values-b861c7-test-4.yaml +++ b/helm/keycloak/values-b861c7-test-4.yaml @@ -2,7 +2,7 @@ replicaCount: 1 image: repository: ghcr.io/bcgov/sso - tag: 7.6.5-build.18 + tag: 7.6.5-build.21 pullPolicy: IfNotPresent rollingUpdate: diff --git a/helm/keycloak/values-b861c7-test-5.yaml b/helm/keycloak/values-b861c7-test-5.yaml index b66784f0..01688cf2 100644 --- a/helm/keycloak/values-b861c7-test-5.yaml +++ b/helm/keycloak/values-b861c7-test-5.yaml @@ -2,7 +2,7 @@ replicaCount: 1 image: repository: ghcr.io/bcgov/sso - tag: 7.6.5-build.18 + tag: 7.6.5-build.21 pullPolicy: IfNotPresent rollingUpdate: diff --git a/helm/keycloak/values-b861c7-test-6.yaml b/helm/keycloak/values-b861c7-test-6.yaml index 040e08ff..88f81941 100644 --- a/helm/keycloak/values-b861c7-test-6.yaml +++ b/helm/keycloak/values-b861c7-test-6.yaml @@ -2,7 +2,7 @@ replicaCount: 1 image: repository: ghcr.io/bcgov/sso - tag: 7.6.5-build.18 + tag: 7.6.5-build.21 pullPolicy: IfNotPresent rollingUpdate: From bbe68d5d72474b656039d4e8cc98f3f50f49cafd Mon Sep 17 00:00:00 2001 From: Junmin Ahn Date: Mon, 21 Nov 2022 12:01:04 -0800 Subject: [PATCH 041/118] chore: update bceid web service helper function --- .../migrations/helpers/migrate-target-bceidboth-users.js | 9 ++++++--- scripts/migrations/test-bceid-webservice.js | 7 ++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/scripts/migrations/helpers/migrate-target-bceidboth-users.js b/scripts/migrations/helpers/migrate-target-bceidboth-users.js index 9d0fdbfe..a2cabc25 100644 --- a/scripts/migrations/helpers/migrate-target-bceidboth-users.js +++ b/scripts/migrations/helpers/migrate-target-bceidboth-users.js @@ -43,13 +43,16 @@ const parseAccount = (data) => { const displayName = _.get(data, 'displayName.0.value.0'); const type = _.get(data, 'type.0.code.0'); const email = _.get(data, 'contact.0.email.0.value.0'); + const telephone = _.get(data, 'contact.0.telephone.0.value.0'); + const firstName = _.get(data, 'individualIdentity.0.name.0.firstname.0.value.0'); + const lastName = _.get(data, 'individualIdentity.0.name.0.surname.0.value.0'); const businessGuid = _.get(data, 'business.0.guid.0.value.0'); const businessLegalName = _.get(data, 'business.0.legalName.0.value.0'); - return { guid, userId, displayName, type, email, businessGuid, businessLegalName }; + return { guid, userId, displayName, type, email, telephone, firstName, lastName, businessGuid, businessLegalName }; }; -const fetchBceidUser = async ({ accountType = 'Business', matchKey = '', env = 'dev' }) => { +const fetchBceidUser = async ({ accountType = 'Business', property = 'userGuid', matchKey = '', env = 'dev' }) => { let serviceUrl = ''; let serviceId = ''; if (env === 'dev') { @@ -63,7 +66,7 @@ const fetchBceidUser = async ({ accountType = 'Business', matchKey = '', env = ' serviceId = process.env.BCEID_SERVICE_ID_PROD; } - const xml = generateXML({ accountType, matchKey, serviceId }); + const xml = generateXML({ accountType, property, matchKey, serviceId }); try { const { response } = await soapRequest({ diff --git a/scripts/migrations/test-bceid-webservice.js b/scripts/migrations/test-bceid-webservice.js index 8bdf0097..04f25ef5 100644 --- a/scripts/migrations/test-bceid-webservice.js +++ b/scripts/migrations/test-bceid-webservice.js @@ -3,7 +3,7 @@ const { argv } = require('yargs'); const Confirm = require('prompt-confirm'); const { handleError, ignoreError } = require('../helpers'); const { fetchBceidUser } = require('./helpers/migrate-target-bceidboth-users'); -const { type, search, env, auto } = argv; +const { type, search, property, env, auto } = argv; async function main() { if (!env) { @@ -14,7 +14,8 @@ async function main() { Flags: --env BCeID Client environment; dev | test | prod --type BCeID account type; Business | Individual - --search BCeID account GUID to search for + --property BCeID search property; userGuid | userId + --search BCeID account search value --auto Skips the confirmation before running the script `); @@ -28,7 +29,7 @@ async function main() { if (!answer) return; } - const result = await fetchBceidUser({ accountType: type, matchKey: search, env }); + const result = await fetchBceidUser({ accountType: type, property, matchKey: search, env }); console.log('result', result); process.exit(0); From 3d1278d86e00dd09b02ecf90943f6dad57308b19 Mon Sep 17 00:00:00 2001 From: Junmin Ahn Date: Mon, 21 Nov 2022 12:06:39 -0800 Subject: [PATCH 042/118] chore: add a kc script to print terraform import statements --- ...dard-client-rep-roles-terraform-imports.js | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 scripts/keycloak-gold-standard-client-rep-roles-terraform-imports.js diff --git a/scripts/keycloak-gold-standard-client-rep-roles-terraform-imports.js b/scripts/keycloak-gold-standard-client-rep-roles-terraform-imports.js new file mode 100644 index 00000000..03e4f8aa --- /dev/null +++ b/scripts/keycloak-gold-standard-client-rep-roles-terraform-imports.js @@ -0,0 +1,88 @@ +const _ = require('lodash'); +const { argv } = require('yargs'); +const Confirm = require('prompt-confirm'); +const { getAdminClient } = require('./keycloak-core'); +const { handleError, ignoreError } = require('./helpers'); +const { env, auto } = argv; + +const prefix = 'client-'; + +const envMap = { + alpha: 'dev', + beta: 'test', + gamma: 'prod', +}; + +async function main() { + if (!env || !['alpha', 'beta', 'gamma'].includes(env)) { + console.info(` +Prints Terraform import statements to import the standard client-representative realm roles. + +Usages: + node keycloak-gold-standard-client-rep-roles-terraform-imports --env [--auto] +`); + + return; + } + + try { + const adminClient = await getAdminClient(env); + if (!adminClient) return; + + if (!auto) { + const prompt = new Confirm(`Are you sure to proceed?`); + const answer = await prompt.run(); + if (!answer) return; + } + + const max = 500; + let first = 0; + let total = 0; + + const result = []; + + while (true) { + const roles = await adminClient.roles.find({ realm: 'standard' }); + + const count = roles.length; + total += count; + + for (let x = 0; x < roles.length; x++) { + const role = roles[x]; + if (!role.name.startsWith(prefix)) continue; + + const clientId = role.name.substring(prefix.length); + + const clients = await adminClient.clients.find({ realm: 'standard', clientId: clientId }); + if (clients.length === 0) { + console.log(`client not found: ${clientId}`); + continue; + } + + const usersWithRole = await adminClient.roles.findUsersWithRole({ realm: 'standard', name: role.name }); + if (usersWithRole.length === 0) { + continue; + } + + const module = `module.keycloak_${envMap[env]}.module.standard_clients.module.${clientId}.keycloak_role.realm_role`; + const rmCmd = `terraform state rm ${module}`; + const addCmd = `terraform import ${module} standard/${role.id}`; + + result.push(addCmd); + } + + if (count < max) break; + + first = first + max; + } + + console.log(`${total} roles found.`); + result.map((v) => console.log(v)); + process.exit(0); + } catch (err) { + handleError(err); + process.exit(1); + } +} + +main(); From 5a7709643ae269e465ad3ae397a14bf8b7568040 Mon Sep 17 00:00:00 2001 From: Junmin Ahn Date: Mon, 21 Nov 2022 14:35:28 -0800 Subject: [PATCH 043/118] chore: center idp names in idp login themes --- .../src/main/resources/theme/bcgov-idp-login/login/login.ftl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov-idp-login/login/login.ftl b/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov-idp-login/login/login.ftl index f5c3197a..95553f59 100755 --- a/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov-idp-login/login/login.ftl +++ b/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov-idp-login/login/login.ftl @@ -9,7 +9,7 @@ <#list social.providers as p> From 58f89eafc5aa0e9e7c9ee68c12d44bbe6fe1d5f1 Mon Sep 17 00:00:00 2001 From: Nithin Shekar Kuruba <81444731+NithinKuruba@users.noreply.github.com> Date: Tue, 22 Nov 2022 08:43:32 -0800 Subject: [PATCH 044/118] chore: ip and host name are hidden (#235) * chore: ip and host name are hidden * chore: uncommenting rc notifs --- .github/workflows/siteminder-tests.yml | 38 +++++++++----------------- cy-siteminder-tests/README.md | 7 +---- 2 files changed, 14 insertions(+), 31 deletions(-) diff --git a/.github/workflows/siteminder-tests.yml b/.github/workflows/siteminder-tests.yml index 8621df74..d24c7d07 100644 --- a/.github/workflows/siteminder-tests.yml +++ b/.github/workflows/siteminder-tests.yml @@ -6,36 +6,22 @@ on: environment: description: 'Environment under test' required: true - default: 'prod' + default: 'PROD' type: choice - options: ['dev', 'test', 'prod'] + options: ['DEV', 'TEST', 'PROD'] cluster: description: 'OCP' required: true - default: 'gold' + default: 'GOLD' type: choice - options: ['silver', 'gold'] + options: ['SILVER', 'GOLD'] jobs: - matrix-prep: - name: Generate matrix - runs-on: ubuntu-20.04 - outputs: - datacenters: ${{ steps.set-matrix.outputs.datacenters }} - hostname: ${{ steps.set-matrix.outputs.hostname }} - steps: - - name: Fetch environment specific parameters - id: set-matrix - run: | - datacenters=$(echo "${{ secrets.SITEMINDER_TESTS_DATACENTERS }}" | jq '."${{ github.event.inputs.environment }}".datacenters') - hostname=$(echo "${{ secrets.SITEMINDER_TESTS_DATACENTERS }}" | jq -r '."${{ github.event.inputs.environment }}".hostname') - echo ::set-output name=datacenters::{\"include\":$(echo $datacenters)} - echo ::set-output name=hostname::$(echo "$hostname") - run-siteminder-tests: + name: ${{ matrix.name }} runs-on: ubuntu-20.04 - needs: matrix-prep strategy: - matrix: ${{ fromJson(needs.matrix-prep.outputs.datacenters) }} + matrix: + name: ['KAMLOOPS', 'CALGARY'] max-parallel: 1 steps: - name: Check out repository @@ -50,7 +36,7 @@ jobs: - name: Set up docker buildx uses: docker/setup-buildx-action@v2 - name: Cache docker layers - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: /tmp/.buildx-test-cache key: ${{ runner.os }}-buildx-test-${{ github.sha }} @@ -69,18 +55,20 @@ jobs: rm -rf /tmp/.buildx-test-cache mv /tmp/.buildx-test-cache-new /tmp/.buildx-test-cache - name: Run siteminder tests + env: + HOST_ENTRY: ${{ github.event.inputs.environment }}_IDIM_${{ matrix.name }}_HOST run: | cd ${{ github.workspace }}/cy-siteminder-tests docker run --rm -e ENVIRONMENT=${{ github.event.inputs.environment }} \ -e CLUSTER=${{ github.event.inputs.cluster }} \ -v $(pwd)/results:/e2e/results \ - --add-host=${{ needs.matrix-prep.outputs.hostname }}:${{ matrix.ip }} \ + --add-host=${{ secrets[env.HOST_ENTRY] }} \ siteminder-tests - name: Upload test results if: always() - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: - name: ${{ github.event.inputs.cluster }}-${{ github.event.inputs.environment }}-${{ matrix.name }}-results + name: ${{ github.event.inputs.cluster }}-${{ github.event.inputs.environment }}-${{ matrix.name }}-RESULTS path: ${{ github.workspace }}/cy-siteminder-tests/results - name: Rocket.Chat Notification if: failure() diff --git a/cy-siteminder-tests/README.md b/cy-siteminder-tests/README.md index ad2f2be8..f1a13d2f 100644 --- a/cy-siteminder-tests/README.md +++ b/cy-siteminder-tests/README.md @@ -10,12 +10,7 @@ **Note**: The below secrets are used by `siteminder-tests.yml` workflow to run the tests. Make sure these secrets are available as github action secrets before running the github action. These secrets are also stored under a secret `siteminder-tests` at `eb75ad-tools` namespace of gold cluster -- `SITEMINDER_TESTS_DATACENTERS` stores a json payload in below format - - ```json - {\"\":{\"datacenters\":[{\"name\":\"\",\"ip\":\"\"},{\"name\":\"\",\"ip\":\"\"}],\"hostname\":\"\"}} - ``` - +- `SITEMINDER_TESTS_DATACENTERS_HOST_ENTRY` stores datacenter specific hostname and ip address - `SITEMINDER_TESTS_ENV` stores all the key-value pairs from `.env.example` ### Tools From 2f7ff60b9066e27fb98f3e2e01f920c1c05f00f8 Mon Sep 17 00:00:00 2001 From: Junmin Ahn Date: Thu, 24 Nov 2022 14:45:08 -0800 Subject: [PATCH 045/118] chore: update keycloak documentation to list custom extensions --- docker/keycloak/README.md | 89 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 88 insertions(+), 1 deletion(-) diff --git a/docker/keycloak/README.md b/docker/keycloak/README.md index 28c36d15..2d7d6606 100644 --- a/docker/keycloak/README.md +++ b/docker/keycloak/README.md @@ -20,8 +20,95 @@ The `configuration` directory contains the pre-defined Keycloak configuration to ### Authentications - There are three distinct custom authentications to enable Identity Provider (IDP) bindings at the client level rather than sharing all IDPs at the realm level. -- The custom authentications are executed in authentication flow (browser) in their order: +- The custom authentications are executed in authentication flow (browser) in the following order: + 1. `Cookie Stopper`: checks the client-level user sessions and bypasses the further steps. + + - see [`CookieStopAuthenticator.java`](./extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/authenticators/CookieStopAuthenticator.java) + - see [`CookieStopAuthenticatorFactory.java`](./extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/authenticators/CookieStopAuthenticatorFactory.java) + 1. `Identity Provider Stopper`: checks the assigned client roles and redirects if the client binds to a single IDP. + - see [`IdentityProviderStopAuthenticator.java`](./extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/authenticators/IdentityProviderStopAuthenticator.java) + - see [`IdentityProviderStopAuthenticatorFactory.java`](./extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/authenticators/IdentityProviderStopAuthenticatorFactory.java) 1. `Identity Provider Stop Form`: checks the assigned client roles to limit the user's IDP access via UI. - It passes the allowed IDPs into the custom theme `bcgov-idp-stopper` to complete the UI. + - see [`IdentityProviderStopForm.java`](./extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/authenticators/browser/IdentityProviderStopForm.java) + - see [`IdentityProviderStopFormFactory.java`](./extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/authenticators/browser/IdentityProviderStopFormFactory.java) + +- First-login authentications + + 1. `Delete User If Duplicate`: if the authenticated user is a new user, but the Keycloak realm already has an user with the same username, it deletes the existing user so that the new user can be created without an warning message. + - see [`IdpDeleteUserIfDuplicateAuthenticator.java`](./extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/authenticators/broker/IdpDeleteUserIfDuplicateAuthenticator.java) + - see [`IdpDeleteUserIfDuplicateAuthenticatorFactory.java`](./extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/authenticators/broker/IdpDeleteUserIfDuplicateAuthenticatorFactory.java) + +- Post-login authentications + 1. `Client Login Role Binding`: after the user authenticates with a specific client, it assigns the user to the corresponding realm-level role for the client; it creates the role if not exist. + - see [`ClientLoginRoleBinding.java`](./extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/authenticators/ClientLoginRoleBinding.java) + - see [`ClientLoginRoleBindingFactory.java`](./extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/authenticators/ClientLoginRoleBindingFactory.java) + 1. `User Attribute Authenticator`: after the user authenticates, it validates the user based on the user's attribute value; the user is deleted if failed with the validation. + - see [`UserAttributeAuthenticator.java`](./extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/authenticators/UserAttributeAuthenticator.java) + - see [`UserAttributeAuthenticatorFactory.java`](./extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/authenticators/UserAttributeAuthenticatorFactory.java) + +### Broker Procotols + +- there are two custom `OIDC` identity providers + + 1. `Override OIDC Identity Provider`: in order to support the deprecated query param `redirect_uri` in the upstream IDP logout process, it modifies the logout request query params to redirect the user; a new configuration `legacyLogoutRedirectUriSupported` is added in the custom template. + + - config `legacyLogoutRedirectUriSupported`: whether or not the upstream IDP supports legacy logout redirect URI. + - see [`OverrideOIDCIdentityProvider.java`](./extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/broker/oidc/OverrideOIDCIdentityProvider.java) + - see [`OverrideOIDCIdentityProviderFactory.java`](./extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/broker/oidc/OverrideOIDCIdentityProviderFactory.java) + - see [`realm-identity-provider-oidc-ext.html`](./extensions-7.6/themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-oidc-ext.html) + + 1. `Custom OIDC Identity Provider`: it is designed to add a custom logic into the exisiting token validation, but has not been developed since the proof of concept. + - see [`CustomOIDCIdentityProvider.java`](./extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/broker/oidc/CustomOIDCIdentityProvider.java) + - see [`CustomOIDCIdentityProviderFactory.java`](./extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/broker/oidc/CustomOIDCIdentityProviderFactory.java) + - see [`realm-identity-provider-oidc-custom-ext.html`](./extensions-7.6/themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-oidc-custom-ext.html) + +- there is one custom `GitHub` identity provider + + 1. `Custom GitHub Identity Provider`: it validates the GitHub users' org membership to update user attributes `org_verified` and `orgs`. two configurations `githubOrg` and `githubOrgRequired` are added in the custom template. + - config `githubOrg`: a comma-separated list of the target GitHub org names. + - config `githubOrgRequired`: whether or not the org membership is mandatory to authenticate the user. + - see [`CustomGitHubIdentityProvider.java`](./extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/social/github/CustomGitHubIdentityProvider.java) + - see [`CustomGitHubIdentityProviderFactory.java`](./extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/social/github/CustomGitHubIdentityProviderFactory.java) + - see [`CustomGitHubUserAttributeMapper.java`](./extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/social/github/CustomGitHubUserAttributeMapper.java) + - see [`realm-identity-provider-github-custom-ext.html`](./extensions-7.6/themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-github-custom-ext.html) + +### Protocol Mappers + +- there are two custom `OIDC` protocol mappers + + 1. `Omit Claims By IDPs`: it sets an empty string for the target claims by the maching IDP aliases; it has two configurations. + + - config `Identity Provider Aliases`: a comma-separated list of the target IDP aliases; if not specified, the mapper will be always applied. + - config `Token Claim Names`: a comma-separated list of the target token claim names + - see [`ClaimOmitterMapper.java`](./extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/protocol/oidc/mappers/ClaimOmitterMapper.java) + + 1. `IDP Userinfo Mapper`: it inserts the userinfo data, retrieved by the IDP's userinfo endpoint, into the tokens. + +- there is one custom `SAML` protocol mapper + + 1. `Client Role Mapper`: it includes the client-level roles of the authenticated user into the tokens. + - config `Role attribute name`: the name of the SAML attribute you want to put your roles into. i.e. 'Role', 'memberOf'. + - see [`ClientRoleListMapper.java`](./extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/protocol/saml/mappers/ClientRoleListMapper.java) + +### Endpoints + +- there is a custom endpoint under the `OIDC` identity provider base URL to support the backward compatible logout experience. +- see [`LegacyEndpoint.java`](./extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/protocol/oidc/ext/endpoints/LegacyEndpoint.java) + +### Themes + +1. `bcgov`: base theme used for other custom themes and provides the following custom features: + +- it displays `header` and `footer` according to the configurations `kcShowHeader` and `kcShowFooter`. +- it displays the authenticating client's name instead of realm's display name according to the configuration `kcLoginTitleType`. + +1. `bcgov-no-brand`: the same theme as `bcgov` except that it does not display `header` and `footer`. +1. `bcgov-idp-login`: the same theme as `bcgov` except that it does not display `username & password` form. +1. `bcgov-idp-login-no-branch`: the same theme as `bcgov-idp-login` except that it does not display `header` and `footer`. +1. `bcgov-idp-stopper`: the theme specifically designed for the standard realm and provides the following custom features: + +- it displays only allowed IDP options for the authenticating user based on the client. +- it displays the IDP tooltip if the value is specified in the IDP configuration. From 3c3c97686840b61fe920f1bb1640396eca688acf Mon Sep 17 00:00:00 2001 From: Junmin Ahn Date: Fri, 25 Nov 2022 11:37:44 -0800 Subject: [PATCH 046/118] chore: add keycloak scripts --- scripts/.gitignore | 1 + scripts/keycloak-core.js | 1 + ...keycloak-gold-standard-update-idp-links.js | 96 +++++++++++++++ scripts/migrations/export-bceid-users.js | 111 ++++++++++++++++++ scripts/package.json | 2 +- scripts/yarn.lock | 73 ++++++++++++ 6 files changed, 283 insertions(+), 1 deletion(-) create mode 100644 scripts/keycloak-gold-standard-update-idp-links.js create mode 100644 scripts/migrations/export-bceid-users.js diff --git a/scripts/.gitignore b/scripts/.gitignore index 33b6f374..04b22cfb 100644 --- a/scripts/.gitignore +++ b/scripts/.gitignore @@ -1,3 +1,4 @@ node_modules yarn-error.log .env +migrations.*.csv diff --git a/scripts/keycloak-core.js b/scripts/keycloak-core.js index 9b6f5b66..743290ac 100644 --- a/scripts/keycloak-core.js +++ b/scripts/keycloak-core.js @@ -120,6 +120,7 @@ async function getAdminClient(env = 'dev', { totp = '' } = {}) { kcAdminClient.reauth = auth; kcAdminClient.refreshAsNeeded = refreshAsNeeded; + kcAdminClient.url = config.url; await auth(); return kcAdminClient; diff --git a/scripts/keycloak-gold-standard-update-idp-links.js b/scripts/keycloak-gold-standard-update-idp-links.js new file mode 100644 index 00000000..e8877c54 --- /dev/null +++ b/scripts/keycloak-gold-standard-update-idp-links.js @@ -0,0 +1,96 @@ +const _ = require('lodash'); +const { argv } = require('yargs'); +const Confirm = require('prompt-confirm'); +const { getAdminClient } = require('./keycloak-core'); +const { handleError, ignoreError } = require('./helpers'); +const { env, auto } = argv; + +const realm = 'standard'; + +const updateIdpLink = async (adminClient, realm, user) => { + const { id, username } = user; + + const links = await adminClient.users.listFederatedIdentities({ realm, id }); + if (links.length === 0) { + console.log(`no IDP links; user: ${username}`); + return; + } + + const { identityProvider, userId, userName } = links[0]; + if (userId === userName) { + console.log(`already synced; user: ${username}`); + return; + } + + if (userId !== userName) { + await adminClient.users.delFromFederatedIdentity({ realm, id, federatedIdentityId: identityProvider }); + await adminClient.users.addToFederatedIdentity({ + realm, + id, + federatedIdentityId: identityProvider, + federatedIdentity: { + userId: userName, + userName: userName, + identityProvider: identityProvider, + }, + }); + + console.log(`updated; user: ${username}`); + } +}; + +async function main() { + if (!env || !['alpha', 'beta', 'gamma'].includes(env)) { + console.info(` +Updates the standard realm's user IDP links to have Provider IDs as same as the Provider username. + +Usages: + node keycloak-gold-standard-update-idp-links --env [--auto] +`); + + return; + } + + try { + const adminClient = await getAdminClient(env); + if (!adminClient) return; + + if (!auto) { + const prompt = new Confirm(`Are you sure to proceed in ${adminClient.url}?`); + const answer = await prompt.run(); + if (!answer) return; + } + + const starttime = new Date().getTime(); + + const max = 200; + let first = 0; + let total = 0; + + const _updateIdpLink = updateIdpLink.bind(null, adminClient, realm); + + while (true) { + const users = await adminClient.users.find({ realm, first, max }); + + const count = users.length; + total += count; + + await Promise.all(users.map(_updateIdpLink)); + + if (count < max) break; + + first = first + max; + } + + console.log(`${total} users found.`); + + const endtime = new Date().getTime(); + console.log(`took ${(endtime - starttime) / 1000} sec.`); + process.exit(0); + } catch (err) { + handleError(err); + process.exit(1); + } +} + +main(); diff --git a/scripts/migrations/export-bceid-users.js b/scripts/migrations/export-bceid-users.js new file mode 100644 index 00000000..09b0d737 --- /dev/null +++ b/scripts/migrations/export-bceid-users.js @@ -0,0 +1,111 @@ +const fs = require('fs'); +const path = require('path'); +const _ = require('lodash'); +const csv = require('fast-csv'); +const { argv } = require('yargs'); +const Confirm = require('prompt-confirm'); +const { getAdminClient } = require('../keycloak-core'); +const { handleError, ignoreError } = require('../helpers'); +const { fetchBceidUser } = require('./helpers/migrate-target-bceidboth-users'); +const { env, realm, idp, auto } = argv; + +const fetchData = async (adminClient, csvStream, user) => { + const { id, username } = user; + + const links = await adminClient.users.listFederatedIdentities({ realm, id }); + if (links.length === 0) { + console.log(`no IDP links; user: ${username}`); + return; + } + + const { identityProvider, userId, userName } = links[0]; + if (identityProvider !== idp) { + console.log(`no target IDP; user: ${username}`); + return; + } + + const details = + (await fetchBceidUser({ accountType: 'Business', property: 'userId', matchKey: userName, env })) || + (await fetchBceidUser({ accountType: 'Individual', property: 'userId', matchKey: userName, env })); + + if (!details) { + console.log(`not found in web service; user: ${username}`); + csvStream.write({ realm_username: username, status: 'not found' }); + return; + } + + csvStream.write({ + realm_username: username, + status: 'found', + display_name: details.displayName, + bceid_user_guid: details.guid, + bceid_username: details.userId, + bceid_type: details.type, + bceid_business_guid: details.businessGuid, + bceid_business_name: details.businessLegalName, + }); +}; + +async function main() { + if (!env || !realm || !idp || !['dev', 'test', 'prod'].includes(env)) { + console.info(` +Export BCeID user data searched with 'BCeID username' value via Web Service. + +Usages: + node migrations/export-bceid-users --env --realm --idp [--auto] +`); + + return; + } + + try { + const adminClient = await getAdminClient(env); + if (!adminClient) return; + + if (!auto) { + const prompt = new Confirm(`Are you sure to proceed in ${adminClient.url}?`); + const answer = await prompt.run(); + if (!answer) return; + } + + const starttime = new Date().getTime(); + const max = 50; + let first = 0; + let total = 0; + + const csvStream = csv.format({ headers: true }); + const writableStream = fs.createWriteStream( + path.join(__dirname, `bceid-export-${realm}-${env}-${idp}-${starttime}.csv`), + ); + + csvStream.pipe(writableStream).on('end', () => { + const endtime = new Date().getTime(); + console.log(`${total} users found`); + console.log(`took ${(endtime - starttime) / 1000} sec.`); + + process.exit(0); + }); + + const _fetchData = fetchData.bind(null, adminClient, csvStream); + + while (true) { + const users = await adminClient.users.find({ realm, first, max }); + const count = users.length; + total += count; + + await Promise.all(users.map(_fetchData)); + + if (count < max) { + csvStream.end(); + break; + } + + first = first + max; + } + } catch (err) { + handleError(err); + process.exit(1); + } +} + +main(); diff --git a/scripts/package.json b/scripts/package.json index 0d12c977..2b816644 100644 --- a/scripts/package.json +++ b/scripts/package.json @@ -4,13 +4,13 @@ "description": "Javascript scripts for minor updates and aggregations.", "author": "SSO Team", "license": "Apache-2.0", - "dependencies": {}, "devDependencies": { "axios": "^0.21.4", "dotenv": "^10.0.0", "easy-soap-request": "^5.2.0", "jws": "^4.0.0", "keycloak-admin": "^1.14.22", + "fast-csv": "^4.3.6", "lodash": "^4.17.21", "octokit": "^2.0.10", "prompt-confirm": "^2.0.4", diff --git a/scripts/yarn.lock b/scripts/yarn.lock index d4e11354..4be5f318 100644 --- a/scripts/yarn.lock +++ b/scripts/yarn.lock @@ -2,6 +2,31 @@ # yarn lockfile v1 +"@fast-csv/format@4.3.5": + version "4.3.5" + resolved "https://registry.yarnpkg.com/@fast-csv/format/-/format-4.3.5.tgz#90d83d1b47b6aaf67be70d6118f84f3e12ee1ff3" + integrity sha512-8iRn6QF3I8Ak78lNAa+Gdl5MJJBM5vRHivFtMRUWINdevNo00K7OXxS2PshawLKTejVwieIlPmK5YlLu6w4u8A== + dependencies: + "@types/node" "^14.0.1" + lodash.escaperegexp "^4.1.2" + lodash.isboolean "^3.0.3" + lodash.isequal "^4.5.0" + lodash.isfunction "^3.0.9" + lodash.isnil "^4.0.0" + +"@fast-csv/parse@4.3.6": + version "4.3.6" + resolved "https://registry.yarnpkg.com/@fast-csv/parse/-/parse-4.3.6.tgz#ee47d0640ca0291034c7aa94039a744cfb019264" + integrity sha512-uRsLYksqpbDmWaSmzvJcuApSEe38+6NQZBUsuAyMZKqHxH0g1wcJgsKUvN3WC8tewaqFjBMMGrkHmC+T7k8LvA== + dependencies: + "@types/node" "^14.0.1" + lodash.escaperegexp "^4.1.2" + lodash.groupby "^4.6.0" + lodash.isfunction "^3.0.9" + lodash.isnil "^4.0.0" + lodash.isundefined "^3.0.1" + lodash.uniq "^4.5.0" + "@octokit/app@^13.0.5": version "13.0.11" resolved "https://registry.yarnpkg.com/@octokit/app/-/app-13.0.11.tgz#6c61b9a614e0d913e4cb0201bb0911d5115f28c0" @@ -254,6 +279,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.9.tgz#02d013de7058cea16d36168ef2fc653464cfbad4" integrity sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg== +"@types/node@^14.0.1": + version "14.18.33" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.33.tgz#8c29a0036771569662e4635790ffa9e057db379b" + integrity sha512-qelS/Ra6sacc4loe/3MSjXNL1dNQ/GjxNHVzuChwMfmk7HuycRLVQN2qNY3XahK+fZc5E2szqQSKUyAF0E+2bg== + aggregate-error@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" @@ -733,6 +763,14 @@ extend-shallow@^2.0.1: dependencies: is-extendable "^0.1.0" +fast-csv@^4.3.6: + version "4.3.6" + resolved "https://registry.yarnpkg.com/fast-csv/-/fast-csv-4.3.6.tgz#70349bdd8fe4d66b1130d8c91820b64a21bc4a63" + integrity sha512-2RNSpuwwsJGP0frGsOmTb9oUF+VkFSM4SyLTDgwf2ciHWTarN0lQTC+F2f/t5J9QjW+c65VFIAAu85GsvMIusw== + dependencies: + "@fast-csv/format" "4.3.5" + "@fast-csv/parse" "4.3.6" + filter-obj@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/filter-obj/-/filter-obj-1.1.0.tgz#9b311112bc6c6127a16e016c6c5d7f19e0805c5b" @@ -999,6 +1037,16 @@ lazy-cache@^2.0.1: dependencies: set-getter "^0.1.0" +lodash.escaperegexp@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz#64762c48618082518ac3df4ccf5d5886dae20347" + integrity sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw== + +lodash.groupby@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.groupby/-/lodash.groupby-4.6.0.tgz#0b08a1dcf68397c397855c3239783832df7403d1" + integrity sha512-5dcWxm23+VAoz+awKmBaiBvzox8+RqMgFhi7UvX9DHZr2HdxHXM/Wrf8cfKpsW37RNrvtPn6hSwNqurSILbmJw== + lodash.includes@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" @@ -1009,11 +1057,26 @@ lodash.isboolean@^3.0.3: resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" integrity sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg== +lodash.isequal@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" + integrity sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ== + +lodash.isfunction@^3.0.9: + version "3.0.9" + resolved "https://registry.yarnpkg.com/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz#06de25df4db327ac931981d1bdb067e5af68d051" + integrity sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw== + lodash.isinteger@^4.0.4: version "4.0.4" resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" integrity sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA== +lodash.isnil@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/lodash.isnil/-/lodash.isnil-4.0.0.tgz#49e28cd559013458c814c5479d3c663a21bfaa6c" + integrity sha512-up2Mzq3545mwVnMhTDMdfoG1OurpA/s5t88JmQX809eH3C8491iu2sfKhTfhQtKY78oPNhiaHJUpT/dUDAAtng== + lodash.isnumber@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" @@ -1029,11 +1092,21 @@ lodash.isstring@^4.0.1: resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" integrity sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw== +lodash.isundefined@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash.isundefined/-/lodash.isundefined-3.0.1.tgz#23ef3d9535565203a66cefd5b830f848911afb48" + integrity sha512-MXB1is3s899/cD8jheYYE2V9qTHwKvt+npCwpD+1Sxm3Q3cECXCiYHjeHWXNwr6Q0SOBPrYUDxendrO6goVTEA== + lodash.once@^4.0.0: version "4.1.1" resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg== +lodash.uniq@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" + integrity sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ== + lodash@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" From 179438bb55bce474761defa62752f963b1a11711 Mon Sep 17 00:00:00 2001 From: Nithin Shekar Kuruba <81444731+NithinKuruba@users.noreply.github.com> Date: Fri, 25 Nov 2022 14:14:14 -0800 Subject: [PATCH 047/118] Refactored code to read new SAML response (#238) * chore: refactor code to read new saml response * chore: removed log commands * chore: check default response obj first --- .../cypress/support/commands.ts | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/cy-siteminder-tests/cypress/support/commands.ts b/cy-siteminder-tests/cypress/support/commands.ts index d841f32a..9d8dc7a0 100644 --- a/cy-siteminder-tests/cypress/support/commands.ts +++ b/cy-siteminder-tests/cypress/support/commands.ts @@ -64,13 +64,26 @@ Cypress.Commands.add( const cleanSamlResponse = entries.SAMLResponse.replace(/(\r\n|\n|\r)/gm, '') const decodedXML = decodeBase64(cleanSamlResponse) const jsonResult = await parseStringSync(decodedXML) - const assertion = _.get(jsonResult, 'Response.ns2:Assertion.0') + let assertion + if (_.get(jsonResult, 'Response.ns2:Assertion.0')) { + assertion = _.get(jsonResult, 'Response.ns2:Assertion.0') + } else { + assertion = _.get(jsonResult, 'ns5:Response.ns2:Assertion.0') + } + const getAttributea = (data: any) => ({}) - const getAttribute = (data: any) => ({ - [_.get(data, '$.Name')]: _.get(data, 'ns2:AttributeValue.0'), - }) + const getAttribute = (data: any) => { + let val + if (typeof _.get(data, 'ns2:AttributeValue.0') === 'object') { + val = Object.values(_.get(data, 'ns2:AttributeValue.0'))[0] + } else { + val = _.get(data, 'ns2:AttributeValue.0') + } + return { + [_.get(data, '$.Name')]: val, + } + } const statements = _.get(assertion, 'ns2:AttributeStatement.0.ns2:Attribute') - const attributes = _.reduce( statements, (ret: any, data: any) => ({ ...ret, ...getAttribute(data) }), @@ -102,7 +115,6 @@ const decodeBase64 = (data: any) => { const updateSiteminderVals = (attributes: any) => { const result: any = {} - result.guid = attributes['useridentifier'] ?? attributes['SMGOV_USERGUID'] ?? '' result.username = attributes['username'] result.email = attributes['email'] From 47a888b54d96cf8833ec9e3fb4410116c239e8f0 Mon Sep 17 00:00:00 2001 From: Junmin Ahn Date: Mon, 28 Nov 2022 14:21:46 -0800 Subject: [PATCH 048/118] feat: add saml client mapper to remove target statement attributes --- docker/keycloak/README.md | 9 +- .../StatementAttributeOmitterMapper.java | 117 ++++++++++++++++++ .../org.keycloak.protocol.ProtocolMapper | 1 + 3 files changed, 126 insertions(+), 1 deletion(-) create mode 100755 docker/keycloak/extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/protocol/saml/mappers/StatementAttributeOmitterMapper.java diff --git a/docker/keycloak/README.md b/docker/keycloak/README.md index 2d7d6606..dec52108 100644 --- a/docker/keycloak/README.md +++ b/docker/keycloak/README.md @@ -87,12 +87,19 @@ The `configuration` directory contains the pre-defined Keycloak configuration to 1. `IDP Userinfo Mapper`: it inserts the userinfo data, retrieved by the IDP's userinfo endpoint, into the tokens. -- there is one custom `SAML` protocol mapper +- there are two custom `SAML` protocol mappers 1. `Client Role Mapper`: it includes the client-level roles of the authenticated user into the tokens. + - config `Role attribute name`: the name of the SAML attribute you want to put your roles into. i.e. 'Role', 'memberOf'. - see [`ClientRoleListMapper.java`](./extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/protocol/saml/mappers/ClientRoleListMapper.java) + 1. `Omit Statement Attributes By IDPs`: it removes the target SAML satement attributes by the maching IDP aliases; it has two configurations. + + - config `Identity Provider Aliases`: a comma-separated list of the target IDP aliases; if not specified, the mapper will be always applied. + - config `Statement Attribute Names`: a comma-separated list of the target statement attribute names + - see [`StatementAttributeOmitterMapper.java`](./extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/protocol/saml/mappers/StatementAttributeOmitterMapper.java) + ### Endpoints - there is a custom endpoint under the `OIDC` identity provider base URL to support the backward compatible logout experience. diff --git a/docker/keycloak/extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/protocol/saml/mappers/StatementAttributeOmitterMapper.java b/docker/keycloak/extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/protocol/saml/mappers/StatementAttributeOmitterMapper.java new file mode 100755 index 00000000..412164d3 --- /dev/null +++ b/docker/keycloak/extensions-7.6/services/src/main/java/com/github/bcgov/keycloak/protocol/saml/mappers/StatementAttributeOmitterMapper.java @@ -0,0 +1,117 @@ +package com.github.bcgov.keycloak.protocol.saml.mappers; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.jboss.logging.Logger; +import org.keycloak.dom.saml.v2.assertion.AttributeStatementType; +import org.keycloak.models.AuthenticatedClientSessionModel; +import org.keycloak.models.KeycloakSession; +import org.keycloak.models.ProtocolMapperModel; +import org.keycloak.models.UserSessionModel; +import org.keycloak.protocol.saml.SamlProtocol; +import org.keycloak.protocol.saml.mappers.AbstractSAMLProtocolMapper; +import org.keycloak.protocol.saml.mappers.AttributeStatementHelper; +import org.keycloak.protocol.saml.mappers.SAMLAttributeStatementMapper; +import org.keycloak.provider.ProviderConfigProperty; + +/** @author Junmin Ahn */ +public class StatementAttributeOmitterMapper extends AbstractSAMLProtocolMapper + implements SAMLAttributeStatementMapper { + private static final Logger logger = Logger.getLogger(StatementAttributeOmitterMapper.class); + + public static final String IDP_ALIASES = "identity_provider_aliases"; + public static final String STATEMENT_ATTRIBUTE_NAMES = "statement_attribute_names"; + + public static final String PROVIDER_ID = "saml-omit-statement-attributes-by-idp-mapper"; + private static final List configProperties = + new ArrayList(); + + static { + ProviderConfigProperty config = new ProviderConfigProperty(); + config.setName(IDP_ALIASES); + config.setLabel("Identity Provider Aliases"); + config.setHelpText(""); + config.setType(ProviderConfigProperty.STRING_TYPE); + configProperties.add(config); + + config = new ProviderConfigProperty(); + config.setName(STATEMENT_ATTRIBUTE_NAMES); + config.setLabel("Statement Attribute Names"); + config.setHelpText("List of the statement attribute names to remove from the token."); + config.setType(ProviderConfigProperty.STRING_TYPE); + configProperties.add(config); + } + + public List getConfigProperties() { + return configProperties; + } + + @Override + public String getId() { + return PROVIDER_ID; + } + + @Override + public String getDisplayType() { + return "Omit Statement Attributes By IDPs"; + } + + @Override + public String getDisplayCategory() { + return AttributeStatementHelper.ATTRIBUTE_STATEMENT_CATEGORY; + } + + @Override + public String getHelpText() { + return "Omit one or multiple statement attributes"; + } + + public void transformAttributeStatement( + AttributeStatementType attributeStatement, + ProtocolMapperModel mappingModel, + KeycloakSession session, + UserSessionModel userSession, + AuthenticatedClientSessionModel clientSession) { + String sessionIdpAlias = userSession.getNotes().get("identity_provider"); + String idpAliases = mappingModel.getConfig().get(IDP_ALIASES); + String[] idpAliasArr = idpAliases == null ? new String[0] : idpAliases.split(" "); + + if (idpAliasArr.length > 0) { + if (sessionIdpAlias == null || sessionIdpAlias.trim().isEmpty()) return; + if (!Arrays.asList(idpAliasArr).contains(sessionIdpAlias)) return; + } + + String statementAttributes = mappingModel.getConfig().get(STATEMENT_ATTRIBUTE_NAMES); + String[] statementAttributeArr = + statementAttributes == null ? new String[0] : statementAttributes.split(" "); + + if (statementAttributeArr.length == 0) return; + + List attributes = attributeStatement.getAttributes(); + + for (int i = attributes.size(); i-- > 0; ) { + AttributeStatementType.ASTChoiceType attribute = attributes.get(i); + String name = attribute.getAttribute().getName(); + for (String statAttrName : statementAttributeArr) { + if (statAttrName.equals(name)) { + attributeStatement.removeAttribute(attribute); + break; + } + } + } + } + + public static ProtocolMapperModel create(String name) { + ProtocolMapperModel mapper = new ProtocolMapperModel(); + mapper.setName(name); + mapper.setProtocolMapper(PROVIDER_ID); + mapper.setProtocol(SamlProtocol.LOGIN_PROTOCOL); + return mapper; + } + + @Override + public int getPriority() { + return 99; + } +} diff --git a/docker/keycloak/extensions-7.6/services/src/main/resources/META-INF/services/org.keycloak.protocol.ProtocolMapper b/docker/keycloak/extensions-7.6/services/src/main/resources/META-INF/services/org.keycloak.protocol.ProtocolMapper index bfc65670..c622184a 100644 --- a/docker/keycloak/extensions-7.6/services/src/main/resources/META-INF/services/org.keycloak.protocol.ProtocolMapper +++ b/docker/keycloak/extensions-7.6/services/src/main/resources/META-INF/services/org.keycloak.protocol.ProtocolMapper @@ -1,3 +1,4 @@ com.github.bcgov.keycloak.protocol.oidc.mappers.IDPUserinfoMapper com.github.bcgov.keycloak.protocol.oidc.mappers.ClaimOmitterMapper com.github.bcgov.keycloak.protocol.saml.mappers.ClientRoleListMapper +com.github.bcgov.keycloak.protocol.saml.mappers.StatementAttributeOmitterMapper From 5d9cc8830bee7e7b981c5049ef1b3296bed7ff52 Mon Sep 17 00:00:00 2001 From: Junmin Ahn Date: Mon, 28 Nov 2022 14:28:02 -0800 Subject: [PATCH 049/118] feat: add suffix into custom script/style files --- .../login/resources/css/{bcsans.css => bcsans-20221128.css} | 0 .../login/resources/css/{styles.css => styles-20221128.css} | 0 .../login/resources/js/{script.js => script-20221128.js} | 0 .../src/main/resources/theme/bcgov/login/theme.properties | 4 ++-- 4 files changed, 2 insertions(+), 2 deletions(-) rename docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov/login/resources/css/{bcsans.css => bcsans-20221128.css} (100%) rename docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov/login/resources/css/{styles.css => styles-20221128.css} (100%) rename docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov/login/resources/js/{script.js => script-20221128.js} (100%) diff --git a/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov/login/resources/css/bcsans.css b/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov/login/resources/css/bcsans-20221128.css similarity index 100% rename from docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov/login/resources/css/bcsans.css rename to docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov/login/resources/css/bcsans-20221128.css diff --git a/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov/login/resources/css/styles.css b/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov/login/resources/css/styles-20221128.css similarity index 100% rename from docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov/login/resources/css/styles.css rename to docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov/login/resources/css/styles-20221128.css diff --git a/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov/login/resources/js/script.js b/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov/login/resources/js/script-20221128.js similarity index 100% rename from docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov/login/resources/js/script.js rename to docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov/login/resources/js/script-20221128.js diff --git a/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov/login/theme.properties b/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov/login/theme.properties index f2b6f313..3d065bf0 100644 --- a/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov/login/theme.properties +++ b/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov/login/theme.properties @@ -1,7 +1,7 @@ parent=keycloak import=common/keycloak -styles=css/login.css css/tile.css css/bcsans.css css/styles.css -scripts=js/script.js +styles=css/login.css css/tile.css css/bcsans-20221128.css css/styles-20221128.css +scripts=js/script-20221128.js absoluteScripts=https://unpkg.com/@popperjs/core@2 https://unpkg.com/tippy.js@6 kcLoginTitleType=realm From ef0f3e7bbace08d36748ad47679a735f0cd63e10 Mon Sep 17 00:00:00 2001 From: Junmin Ahn Date: Mon, 28 Nov 2022 14:43:13 -0800 Subject: [PATCH 050/118] chore: check context field in bcgov-idp-stopper --- .../src/main/resources/theme/bcgov-idp-stopper/login/login.ftl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov-idp-stopper/login/login.ftl b/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov-idp-stopper/login/login.ftl index 2c97f171..d798f9d2 100755 --- a/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov-idp-stopper/login/login.ftl +++ b/docker/keycloak/extensions-7.6/themes/src/main/resources/theme/bcgov-idp-stopper/login/login.ftl @@ -3,7 +3,7 @@ <#if section = "header"> ${msg("loginAccountTitle")} <#elseif section = "socialProviders"> - <#if social.providers??> + <#if social.providers?? && (login.username)??>