From 1e7b4213551b6ecc4422fa9043c249521c1636bb Mon Sep 17 00:00:00 2001 From: Ryan Liang <109499885+RyanL1997@users.noreply.github.com> Date: Tue, 3 Oct 2023 08:06:35 -0700 Subject: [PATCH 01/32] CI fixes for adapting admin password change and fix the Cypress browser (#1596) * Add the random admin password flow Signed-off-by: Ryan Liang * Pass --headless=old Signed-off-by: Ryan Liang * Switch to firefox for cypress Signed-off-by: Ryan Liang * Fix the typo of firefox driver Signed-off-by: Ryan Liang * Directly changed admin password into admin in ci Signed-off-by: Ryan Liang --------- Signed-off-by: Ryan Liang --- .github/workflows/cypress-test-tenancy-disabled.yml | 3 ++- .github/workflows/cypress-test.yml | 9 +++++---- .github/workflows/integration-test.yml | 3 ++- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/.github/workflows/cypress-test-tenancy-disabled.yml b/.github/workflows/cypress-test-tenancy-disabled.yml index 23494d1c3..3c6c084cf 100644 --- a/.github/workflows/cypress-test-tenancy-disabled.yml +++ b/.github/workflows/cypress-test-tenancy-disabled.yml @@ -50,6 +50,7 @@ jobs: opensearch-version: ${{ env.OPENSEARCH_VERSION }} plugin-name: ${{ env.PLUGIN_NAME }} setup-script-name: setup + admin-password: admin - name: Run Dashboard with Security Dashboards Plugin uses: ./.github/actions/install-dashboards @@ -73,4 +74,4 @@ jobs: git clone https://github.com/opensearch-project/opensearch-dashboards-functional-test.git cd opensearch-dashboards-functional-test npm install cypress --save-dev - yarn cypress:run-with-security --browser chrome --spec "cypress/integration/plugins/security-dashboards-plugin/inaccessible_tenancy_features.js" + yarn cypress:run-with-security --browser firefox --spec "cypress/integration/plugins/security-dashboards-plugin/inaccessible_tenancy_features.js" diff --git a/.github/workflows/cypress-test.yml b/.github/workflows/cypress-test.yml index c5e5370c1..745ef077d 100644 --- a/.github/workflows/cypress-test.yml +++ b/.github/workflows/cypress-test.yml @@ -20,7 +20,7 @@ jobs: os: [ ubuntu-latest , windows-latest ] runs-on: ${{ matrix.os }} - steps: + steps: - name: Set up JDK uses: actions/setup-java@v1 with: @@ -50,6 +50,7 @@ jobs: opensearch-version: ${{ env.OPENSEARCH_VERSION }} plugin-name: ${{ env.PLUGIN_NAME }} setup-script-name: setup + admin-password: admin - name: Run Dashboard with Security Dashboards Plugin uses: ./.github/actions/install-dashboards @@ -75,6 +76,6 @@ jobs: git clone https://github.com/opensearch-project/opensearch-dashboards-functional-test.git cd opensearch-dashboards-functional-test npm install cypress --save-dev - yarn cypress:run-with-security-and-aggregation-view --browser chrome --spec "cypress/integration/plugins/security-dashboards-plugin/aggregation_view.js" - yarn cypress:run-with-security --browser chrome --spec "cypress/integration/plugins/security-dashboards-plugin/multi_tenancy.js" - yarn cypress:run-with-security --browser chrome --spec "cypress/integration/plugins/security-dashboards-plugin/default_tenant.js" + yarn cypress:run-with-security-and-aggregation-view --browser firefox --spec "cypress/integration/plugins/security-dashboards-plugin/aggregation_view.js" + yarn cypress:run-with-security --browser firefox --spec "cypress/integration/plugins/security-dashboards-plugin/multi_tenancy.js" + yarn cypress:run-with-security --browser firefox --spec "cypress/integration/plugins/security-dashboards-plugin/default_tenant.js" diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index a3d6f70d1..7ac0dba0a 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -19,7 +19,7 @@ jobs: steps: - name: Checkout Branch uses: actions/checkout@v3 - + - name: Set up JDK uses: actions/setup-java@v1 with: @@ -64,6 +64,7 @@ jobs: opensearch-version: ${{ env.OPENSEARCH_VERSION }} plugin-name: ${{ env.PLUGIN_NAME }} setup-script-name: setup + admin-password: admin - id: install-dashboards uses: ./.github/actions/install-dashboards From d575e0001c406149a9df6e6c52c00057738e7536 Mon Sep 17 00:00:00 2001 From: Jochen Kressin <126353411+jochen-kressin@users.noreply.github.com> Date: Thu, 5 Oct 2023 23:22:29 +0200 Subject: [PATCH 02/32] The cookie splitter should be able to use cookie values that have been set within the current request (#1580) Signed-off-by: Jochen Kressin Co-authored-by: Darshit Chanpura <35282393+DarshitChanpura@users.noreply.github.com> --- server/session/cookie_splitter.test.ts | 65 ++++++++++++++++++++++++++ server/session/cookie_splitter.ts | 24 +++++++++- 2 files changed, 87 insertions(+), 2 deletions(-) diff --git a/server/session/cookie_splitter.test.ts b/server/session/cookie_splitter.test.ts index 833987427..73745d59a 100644 --- a/server/session/cookie_splitter.test.ts +++ b/server/session/cookie_splitter.test.ts @@ -14,6 +14,7 @@ */ import { Request as HapiRequest, ResponseObject as HapiResponseObject } from '@hapi/hapi'; import { httpServerMock } from '../../../../src/core/server/http/http_server.mocks'; +import { merge } from 'lodash'; import { clearSplitCookies, getExtraAuthStorageValue, @@ -171,4 +172,68 @@ describe('Test extra auth storage', () => { expect(unsplitValue).toEqual('abcdefghi'); }); + + test('should check for cookie values updated in the same request', async () => { + const cookiePrefix = 'testcookie'; + const additionalCookies = 5; + + const mockRequest = httpServerMock.createRawRequest(); + + const extendedMockRequest = merge(mockRequest, { + _states: { + [cookiePrefix + '1']: { + name: cookiePrefix + '1', + value: 'abc', + }, + [cookiePrefix + '2']: { + name: cookiePrefix + '2', + value: 'def', + }, + [cookiePrefix + '3']: { + name: cookiePrefix + '3', + value: 'ghi', + }, + }, + }) as HapiRequest; + + const osRequest = OpenSearchDashboardsRequest.from(extendedMockRequest); + const unsplitValue = unsplitCookiesIntoValue(osRequest, cookiePrefix, additionalCookies); + + expect(unsplitValue).toEqual('abcdefghi'); + }); + + test('should not mix cookie values updated in the same request with previous cookie values', async () => { + const cookiePrefix = 'testcookie'; + const additionalCookies = 5; + + const mockRequest = httpServerMock.createRawRequest({ + state: { + [cookiePrefix + '1']: 'abc', + [cookiePrefix + '2']: 'def', + [cookiePrefix + '3']: 'ghi', + }, + }); + + const extendedMockRequest = merge(mockRequest, { + _states: { + [cookiePrefix + '1']: { + name: cookiePrefix + '1', + value: 'jkl', + }, + [cookiePrefix + '2']: { + name: cookiePrefix + '2', + value: 'mno', + }, + [cookiePrefix + '3']: { + name: cookiePrefix + '3', + value: 'pqr', + }, + }, + }) as HapiRequest; + + const osRequest = OpenSearchDashboardsRequest.from(extendedMockRequest); + const unsplitValue = unsplitCookiesIntoValue(osRequest, cookiePrefix, additionalCookies); + + expect(unsplitValue).toEqual('jklmnopqr'); + }); }); diff --git a/server/session/cookie_splitter.ts b/server/session/cookie_splitter.ts index c6b563902..33b3ca12d 100644 --- a/server/session/cookie_splitter.ts +++ b/server/session/cookie_splitter.ts @@ -29,6 +29,15 @@ export interface ExtraAuthStorageOptions { type CookieAuthWithResponseObject = HapiRequest['cookieAuth'] & { h: HapiResponseObject }; +interface HapiStates { + [cookieName: string]: { + name: string; + value: string; + }; +} + +export type HapiRequestWithStates = HapiRequest & { _states: HapiStates }; + export function getExtraAuthStorageValue( request: OpenSearchDashboardsRequest, options: ExtraAuthStorageOptions @@ -134,12 +143,23 @@ export function unsplitCookiesIntoValue( cookiePrefix: string, additionalCookies: number ): string { - const rawRequest: HapiRequest = ensureRawRequest(request); + const rawRequest: HapiRequestWithStates = ensureRawRequest(request) as HapiRequestWithStates; let fullCookieValue = ''; + // We don't want to mix and match between _states and .state. + // If we find the first additional cookie in _states, we + // use _states for all subsequent additional cookies + const requestHasNewerCookieState = rawRequest._states && rawRequest._states[cookiePrefix + 1]; + for (let i = 1; i <= additionalCookies; i++) { const cookieName = cookiePrefix + i; - if (rawRequest.state[cookieName]) { + if ( + requestHasNewerCookieState && + rawRequest._states[cookieName] && + rawRequest._states[cookieName].value + ) { + fullCookieValue = fullCookieValue + rawRequest._states[cookieName].value; + } else if (!requestHasNewerCookieState && rawRequest.state[cookieName]) { fullCookieValue = fullCookieValue + rawRequest.state[cookieName]; } } From d3b3f84d988e10d848cd8cd71828145d39c9768f Mon Sep 17 00:00:00 2001 From: Darshit Chanpura <35282393+DarshitChanpura@users.noreply.github.com> Date: Thu, 12 Oct 2023 11:50:25 -0400 Subject: [PATCH 03/32] Adds 2.11.0.0 release notes (#1600) --- ...rch-security-dashboards-plugin.release-notes-2.11.0.0.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 release-notes/opensearch-security-dashboards-plugin.release-notes-2.11.0.0.md diff --git a/release-notes/opensearch-security-dashboards-plugin.release-notes-2.11.0.0.md b/release-notes/opensearch-security-dashboards-plugin.release-notes-2.11.0.0.md new file mode 100644 index 000000000..d19c29f8d --- /dev/null +++ b/release-notes/opensearch-security-dashboards-plugin.release-notes-2.11.0.0.md @@ -0,0 +1,6 @@ +## 2023-10-18 Version 2.11.0.0 + +Compatible with OpenSearch-Dashboards 2.11.0 + +### Bug Fixes +* Fix OIDC refresh token flow when using the cookie splitter ([#1580](https://github.com/opensearch-project/security-dashboards-plugin/pull/1580)) From d97192d2ec82df21001d577e46dcd7a70304e974 Mon Sep 17 00:00:00 2001 From: Craig Perkins Date: Fri, 20 Oct 2023 10:09:00 -0400 Subject: [PATCH 04/32] Add filter when checking out OpenSearch-Dashboards to speed up CI checks (#1613) Signed-off-by: Craig Perkins Signed-off-by: Craig Perkins Co-authored-by: Darshit Chanpura --- .github/actions/download-plugin/action.yml | 2 ++ .github/actions/install-dashboards/action.yml | 3 +++ .github/workflows/integration-test.yml | 12 +++++++++++- 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/.github/actions/download-plugin/action.yml b/.github/actions/download-plugin/action.yml index bbec33c8a..d50cfffd4 100644 --- a/.github/actions/download-plugin/action.yml +++ b/.github/actions/download-plugin/action.yml @@ -32,6 +32,7 @@ runs: chmod +x ./opensearch-${{ inputs.opensearch-version}}-SNAPSHOT/plugins/${{ inputs.plugin-name }}/tools/install_demo_configuration.sh /bin/bash -c "yes | ./opensearch-${{ inputs.opensearch-version}}-SNAPSHOT/plugins/${{ inputs.plugin-name }}/tools/install_demo_configuration.sh" echo "plugins.security.unsupported.restapi.allow_securityconfig_modification: true" >> ./opensearch-${{ inputs.opensearch-version }}-SNAPSHOT/config/opensearch.yml + echo "cluster.routing.allocation.disk.threshold_enabled: false" >> ./opensearch-${{ inputs.opensearch-version }}-SNAPSHOT/config/opensearch.yml EOF shell: bash @@ -41,5 +42,6 @@ runs: New-Item .\setup.bat -type file Set-Content .\setup.bat -Value "powershell.exe -noexit -command `".\opensearch-${{ inputs.opensearch-version}}-SNAPSHOT\plugins\${{ inputs.plugin-name }}\tools\install_demo_configuration.bat -y -i -c`"" Add-Content -Path .\setup.bat -Value "echo plugins.security.unsupported.restapi.allow_securityconfig_modification: true >> .\opensearch-${{ inputs.opensearch-version}}-SNAPSHOT\config\opensearch.yml" + Add-Content -Path .\setup.bat -Value "echo cluster.routing.allocation.disk.threshold_enabled: false >> .\opensearch-${{ inputs.opensearch-version}}-SNAPSHOT\config\opensearch.yml" Get-Content .\setup.bat shell: pwsh diff --git a/.github/actions/install-dashboards/action.yml b/.github/actions/install-dashboards/action.yml index eea6eaf63..1987875e0 100644 --- a/.github/actions/install-dashboards/action.yml +++ b/.github/actions/install-dashboards/action.yml @@ -33,6 +33,9 @@ runs: repository: opensearch-project/OpenSearch-Dashboards ref: 'main' fetch-depth: 0 + filter: | + cypress + test - uses: actions/checkout@v2 with: diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index 7ac0dba0a..22d0d616b 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -66,6 +66,13 @@ jobs: setup-script-name: setup admin-password: admin + # https://github.com/actions/runner-images/issues/2840#issuecomment-790492173 + - name: Remove unnecessary files Linux + if: ${{ runner.os == 'Linux' }} + run: | + sudo rm -rf /usr/share/dotnet + sudo rm -rf "$AGENT_TOOLSDIRECTORY" + - id: install-dashboards uses: ./.github/actions/install-dashboards with: @@ -75,6 +82,9 @@ jobs: run: node scripts/build_opensearch_dashboards_platform_plugins.js working-directory: ${{ steps.install-dashboards.outputs.dashboards-directory }} + - name: Yarn cache clean + run: yarn cache clean + - name: Run integration tests on Linux if: ${{ runner.os == 'Linux' }} run: | @@ -88,5 +98,5 @@ jobs: run: | echo "check if opensearch is ready" curl -XGET https://localhost:9200 -u 'admin:admin' -k - node .\test\run_jest_tests.js --config .\test\jest.config.server.js --testPathIgnorePatterns saml_auth.test.ts --testPathIgnorePatterns saml_multiauth.test.ts + node .\test\run_jest_tests.js --runInBand --detectOpenHandles --forceExit --config .\test\jest.config.server.js --testPathIgnorePatterns saml_auth.test.ts --testPathIgnorePatterns saml_multiauth.test.ts working-directory: ${{ steps.install-dashboards.outputs.plugin-directory }} From 27c37d40221bdc07f0167eca6348806d6b876dd6 Mon Sep 17 00:00:00 2001 From: leanneeliatra <131779422+leanneeliatra@users.noreply.github.com> Date: Mon, 23 Oct 2023 14:39:41 +0100 Subject: [PATCH 05/32] Switch the home link to logout on security error pages (#1564) * changing return to dashboards with functioning logout button on error page Signed-off-by: leanne.laceybyrne@eliatra.com Co-authored-by: Darshit Chanpura <35282393+DarshitChanpura@users.noreply.github.com> Co-authored-by: Peter Nied --- public/apps/customerror/custom-error.tsx | 11 +++- .../__snapshots__/custom-error.test.tsx.snap | 39 ++++++++++++ .../customerror/test/custom-error.test.tsx | 61 +++++++++++++++++++ 3 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 public/apps/customerror/test/__snapshots__/custom-error.test.tsx.snap create mode 100644 public/apps/customerror/test/custom-error.test.tsx diff --git a/public/apps/customerror/custom-error.tsx b/public/apps/customerror/custom-error.tsx index eb4dd9f2e..973068add 100644 --- a/public/apps/customerror/custom-error.tsx +++ b/public/apps/customerror/custom-error.tsx @@ -21,6 +21,7 @@ import { Router, Route } from 'react-router-dom'; import { ERROR_MISSING_ROLE_PATH } from '../../../common'; import { ClientConfigType } from '../../types'; import './_index.scss'; +import { logout } from '../account/utils'; interface CustomErrorDeps { title: string; @@ -45,8 +46,13 @@ export function CustomErrorPage(props: CustomErrorDeps) { {props.subtitle} - - Back to OpenSearch Dashboards Home + logout(props.http, '')} + data-test-subj="error-logout-button" + fullWidth + > + Logout ); @@ -74,3 +80,4 @@ export async function renderPage( ); return () => ReactDOM.unmountComponentAtNode(params.element); } +export { EuiButton }; diff --git a/public/apps/customerror/test/__snapshots__/custom-error.test.tsx.snap b/public/apps/customerror/test/__snapshots__/custom-error.test.tsx.snap new file mode 100644 index 000000000..ceb888fc1 --- /dev/null +++ b/public/apps/customerror/test/__snapshots__/custom-error.test.tsx.snap @@ -0,0 +1,39 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Custom error page test renders and clicks the button on the error page 1`] = ` + + + +

+ Title +

+
+ + + Sub Title + + + + Logout + +
+`; diff --git a/public/apps/customerror/test/custom-error.test.tsx b/public/apps/customerror/test/custom-error.test.tsx new file mode 100644 index 000000000..18291c351 --- /dev/null +++ b/public/apps/customerror/test/custom-error.test.tsx @@ -0,0 +1,61 @@ +/* + * Copyright OpenSearch Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ +import { shallow } from 'enzyme'; +import React from 'react'; +import { CustomErrorPage } from '../custom-error'; +import { cleanup } from '@testing-library/react'; +import '@testing-library/jest-dom'; +import { EuiButton } from '../custom-error'; +import { logout } from '../../account/utils'; + +afterEach(() => { + cleanup(); +}); + +describe('Custom error page test', () => { + let component; + + beforeEach(() => { + component = shallow( + + Logout + + ); + }); + + it('renders and clicks the button on the error page', () => { + const wrapper = shallow( + + ); + + expect(wrapper).toMatchSnapshot(); + + component.find('[data-test-subj="error-logout-button"]').simulate('onClick', { + preventDefault: () => {}, + }); + }); +}); From c7846651e79ecfcbf6fbcfbb577948da52f44126 Mon Sep 17 00:00:00 2001 From: Vamsi Manohar Date: Mon, 23 Oct 2023 18:59:46 -0700 Subject: [PATCH 06/32] Add permissions for async query and patch datasource API (#1626) Signed-off-by: Vamsi Manohar --- public/apps/configuration/constants.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/public/apps/configuration/constants.tsx b/public/apps/configuration/constants.tsx index 25afa303e..e789591cd 100644 --- a/public/apps/configuration/constants.tsx +++ b/public/apps/configuration/constants.tsx @@ -138,6 +138,10 @@ export const CLUSTER_PERMISSIONS: string[] = [ 'cluster:admin/opensearch/ql/datasources/read', 'cluster:admin/opensearch/ql/datasources/update', 'cluster:admin/opensearch/ql/datasources/delete', + 'cluster:admin/opensearch/ql/datasources/patch', + 'cluster:admin/opensearch/ql/async_query/create', + 'cluster:admin/opensearch/ql/async_query/result', + 'cluster:admin/opensearch/ql/async_query/delete', 'cluster:admin/opensearch/ppl', 'cluster:admin/opensearch/ml/create_model_meta', 'cluster:admin/opensearch/ml/execute', From d14bb6875cfec22e1bd790ad7b3103755832a366 Mon Sep 17 00:00:00 2001 From: Derek Ho Date: Thu, 2 Nov 2023 14:53:50 -0400 Subject: [PATCH 07/32] Fix bug where custom permission groups are missing (#1636) Signed-off-by: Derek Ho --- .../panels/role-edit/role-edit.tsx | 18 ++++++++++-- .../test/role-edit-filtering.test.tsx | 29 +++++++++++++++++-- 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/public/apps/configuration/panels/role-edit/role-edit.tsx b/public/apps/configuration/panels/role-edit/role-edit.tsx index 142cba1b3..e5b3c832a 100644 --- a/public/apps/configuration/panels/role-edit/role-edit.tsx +++ b/public/apps/configuration/panels/role-edit/role-edit.tsx @@ -166,12 +166,19 @@ export function RoleEdit(props: RoleEditDeps) { const clusterWisePermissionOptions = [ { - label: 'Permission groups', + label: 'Cluster permission groups', options: actionGroups .filter((actionGroup) => actionGroup[1].type === 'cluster') .map((actionGroup) => actionGroup[0]) .map(stringToComboBoxOption), }, + { + label: 'Other permission groups', + options: actionGroups + .filter((actionGroup) => actionGroup[1].type === undefined) + .map((actionGroup) => actionGroup[0]) + .map(stringToComboBoxOption), + }, { label: 'Cluster permissions', options: CLUSTER_PERMISSIONS.map(stringToComboBoxOption), @@ -180,12 +187,19 @@ export function RoleEdit(props: RoleEditDeps) { const indexWisePermissionOptions = [ { - label: 'Permission groups', + label: 'Index permission groups', options: actionGroups .filter((actionGroup) => actionGroup[1].type === 'index') .map((actionGroup) => actionGroup[0]) .map(stringToComboBoxOption), }, + { + label: 'Other permission groups', + options: actionGroups + .filter((actionGroup) => actionGroup[1].type === undefined) + .map((actionGroup) => actionGroup[0]) + .map(stringToComboBoxOption), + }, { label: 'Index permissions', options: INDEX_PERMISSIONS.map(stringToComboBoxOption), diff --git a/public/apps/configuration/panels/role-edit/test/role-edit-filtering.test.tsx b/public/apps/configuration/panels/role-edit/test/role-edit-filtering.test.tsx index 7142db663..4f3a4f909 100644 --- a/public/apps/configuration/panels/role-edit/test/role-edit-filtering.test.tsx +++ b/public/apps/configuration/panels/role-edit/test/role-edit-filtering.test.tsx @@ -16,7 +16,6 @@ import React from 'react'; import { ClusterPermissionPanel } from '../cluster-permission-panel'; import { RoleEdit } from '../role-edit'; -import { ActionGroupItem } from '../../../types'; import { fetchActionGroups } from '../../../utils/action-groups-utils'; import { render, waitFor } from '@testing-library/react'; @@ -67,6 +66,14 @@ describe('Role edit filtering', () => { description: 'Manage pipelines', static: true, }, + custom: { + reserved: false, + hidden: false, + allowed_actions: ['cluster:admin/ingest/pipeline/*'], + type: undefined, + description: 'Custom group', + static: true, + }, }); it('basic cluster permission panel rendering', async () => { @@ -98,13 +105,21 @@ describe('Role edit filtering', () => { // Cluster Permission Panel props is filtered to action groups with type cluster, and only the cluster permission constants expect(props.optionUniverse).toEqual([ { - label: 'Permission groups', + label: 'Cluster permission groups', options: [ { label: 'cluster_manage_pipelines', }, ], }, + { + label: 'Other permission groups', + options: [ + { + label: 'custom', + }, + ], + }, { label: 'Cluster permissions', options: CLUSTER_PERMISSIONS.map((x) => { @@ -143,13 +158,21 @@ describe('Role edit filtering', () => { // Index Permission Panel props is filtered to action groups with type index, and only the index permission constants expect(props.optionUniverse).toEqual([ { - label: 'Permission groups', + label: 'Index permission groups', options: [ { label: 'data_access', }, ], }, + { + label: 'Other permission groups', + options: [ + { + label: 'custom', + }, + ], + }, { label: 'Index permissions', options: INDEX_PERMISSIONS.map((x) => { From 2131598df843c3d171250067a8a3c26d2fc4e414 Mon Sep 17 00:00:00 2001 From: Prabhas Kurapati <66924475+prabhask5@users.noreply.github.com> Date: Mon, 13 Nov 2023 11:57:35 -0800 Subject: [PATCH 08/32] [Refactor-1160] Different Values Pointing to Basic Auth, Need to Unify (#1619) * finished ticket Signed-off-by: Prabhas Kurapati * fixed invalid auth type error Signed-off-by: Prabhas Kurapati * fixed unit tests Signed-off-by: Prabhas Kurapati * made requested changes Signed-off-by: Prabhas Kurapati * updated saml to AuthType.SAML + fixed basicauth test Signed-off-by: Prabhas Kurapati --------- Signed-off-by: Prabhas Kurapati --- .../apps/account/test/log-out-button.test.tsx | 20 +++------ public/apps/customerror/custom-error.tsx | 3 +- public/apps/login/test/login-page.test.tsx | 11 ++--- server/auth/auth_handler_factory.test.ts | 44 ++++++++++--------- server/auth/types/basic/routes.ts | 5 ++- server/auth/types/saml/saml_auth.ts | 2 +- server/index.ts | 7 +-- server/routes/auth_type_routes.ts | 4 +- test/jest_integration/saml_auth.test.ts | 5 ++- test/jest_integration/saml_multiauth.test.ts | 5 ++- 10 files changed, 55 insertions(+), 51 deletions(-) diff --git a/public/apps/account/test/log-out-button.test.tsx b/public/apps/account/test/log-out-button.test.tsx index 7fd45095a..e8bce80c9 100644 --- a/public/apps/account/test/log-out-button.test.tsx +++ b/public/apps/account/test/log-out-button.test.tsx @@ -17,19 +17,13 @@ import { shallow } from 'enzyme'; import React from 'react'; import { LogoutButton } from '../log-out-button'; import { logout } from '../utils'; +import { AuthType } from '../../../../common'; jest.mock('../utils', () => ({ logout: jest.fn(), })); describe('Account menu - Log out button', () => { - enum authType { - OpenId = 'openid', - SAML = 'saml', - Proxy = 'proxy', - Basic = 'basicauth', - } - const mockHttpStart = { basePath: { serverBasePath: '', @@ -39,42 +33,42 @@ describe('Account menu - Log out button', () => { describe('renders', () => { it('renders when auth type is MultiAuth: openid', () => { const component = shallow( - + ); expect(component).toMatchSnapshot(); }); it('renders when auth type is MultiAuth: saml', () => { const component = shallow( - + ); expect(component).toMatchSnapshot(); }); it('renders when auth type is MultiAuth: basicauth', () => { const component = shallow( - + ); expect(component).toMatchSnapshot(); }); it('renders when auth type is OpenId', () => { const component = shallow( - + ); expect(component).toMatchSnapshot(); }); it('renders when auth type is SAML', () => { const component = shallow( - + ); expect(component).toMatchSnapshot(); }); it('renders when auth type is Proxy', () => { const component = shallow( - + ); expect(component).toMatchSnapshot(); }); diff --git a/public/apps/customerror/custom-error.tsx b/public/apps/customerror/custom-error.tsx index 973068add..4d1729efb 100644 --- a/public/apps/customerror/custom-error.tsx +++ b/public/apps/customerror/custom-error.tsx @@ -20,6 +20,7 @@ import ReactDOM from 'react-dom'; import { Router, Route } from 'react-router-dom'; import { ERROR_MISSING_ROLE_PATH } from '../../../common'; import { ClientConfigType } from '../../types'; +import { AuthType } from '../../../common'; import './_index.scss'; import { logout } from '../account/utils'; @@ -28,7 +29,7 @@ interface CustomErrorDeps { subtitle: string; http: CoreStart['http']; chrome: CoreStart['chrome']; - config: ClientConfigType['ui']['basicauth']['login']; + config: ClientConfigType['ui'][AuthType.BASIC]['login']; } export function CustomErrorPage(props: CustomErrorDeps) { diff --git a/public/apps/login/test/login-page.test.tsx b/public/apps/login/test/login-page.test.tsx index 3c41b17c3..f21a39e5a 100644 --- a/public/apps/login/test/login-page.test.tsx +++ b/public/apps/login/test/login-page.test.tsx @@ -20,6 +20,7 @@ import { LoginPage, extractNextUrlFromWindowLocation } from '../login-page'; import { validateCurrentPassword } from '../../../utils/login-utils'; import { API_AUTH_LOGOUT } from '../../../../common'; import { chromeServiceMock } from '../../../../../../src/core/public/mocks'; +import { AuthType } from '../../../../common'; jest.mock('../../../utils/login-utils', () => ({ validateCurrentPassword: jest.fn(), @@ -101,7 +102,7 @@ describe('Login page', () => { const config: ClientConfigType = { ui: configUI, auth: { - type: ['basicauth'], + type: [AuthType.BASIC], logout_url: API_AUTH_LOGOUT, }, }; @@ -115,7 +116,7 @@ describe('Login page', () => { const config: ClientConfigType = { ui: configUI, auth: { - type: 'basicauth', + type: AuthType.BASIC, logout_url: API_AUTH_LOGOUT, }, }; @@ -129,7 +130,7 @@ describe('Login page', () => { const config: ClientConfigType = { ui: configUI, auth: { - type: ['basicauth', 'openid', 'saml'], + type: [AuthType.BASIC, 'openid', AuthType.SAML], logout_url: API_AUTH_LOGOUT, }, }; @@ -173,7 +174,7 @@ describe('Login page', () => { const config: ClientConfigType = { ui: configUiDefault, auth: { - type: 'basicauth', + type: AuthType.BASIC, }, }; beforeEach(() => { @@ -207,7 +208,7 @@ describe('Login page', () => { const config: ClientConfigType = { ui: configUiDefault, auth: { - type: 'basicauth', + type: AuthType.BASIC, }, }; beforeEach(() => { diff --git a/server/auth/auth_handler_factory.test.ts b/server/auth/auth_handler_factory.test.ts index 71d70ccac..b73bcc2cc 100644 --- a/server/auth/auth_handler_factory.test.ts +++ b/server/auth/auth_handler_factory.test.ts @@ -23,13 +23,17 @@ import { import { SecurityPluginConfigType } from '..'; import { SecuritySessionCookie } from '../session/security_cookie'; import { getAuthenticationHandler } from './auth_handler_factory'; +import { AuthType } from '../../common'; + +const mockBasicAuthType = AuthType.BASIC; +const mockSAMLAuthType = AuthType.SAML; jest.mock('./types', () => { return { BasicAuthentication: jest.fn().mockImplementation(() => { return { authHandler: () => {}, - type: 'basicauth', + type: mockBasicAuthType, init: () => {}, }; }), @@ -57,14 +61,14 @@ jest.mock('./types', () => { SamlAuthentication: jest.fn().mockImplementation(() => { return { authHandler: () => {}, - type: 'saml', + type: mockSAMLAuthType, init: () => {}, }; }), MultipleAuthentication: jest.fn().mockImplementation(() => { return { authHandler: () => {}, - type: ['openid', 'saml', 'basiauth'], + type: ['openid', mockSAMLAuthType, mockBasicAuthType], init: () => {}, }; }), @@ -83,7 +87,7 @@ describe('test authentication factory', () => { test('get basic auth: string array', async () => { const auth = await getAuthenticationHandler( - ['basicauth'], + [AuthType.BASIC], router, config, core, @@ -91,12 +95,12 @@ describe('test authentication factory', () => { sessionStorageFactory, logger ); - expect(auth.type).toEqual('basicauth'); + expect(auth.type).toEqual(AuthType.BASIC); }); test('get basic auth: string', async () => { const auth = await getAuthenticationHandler( - 'basicauth', + AuthType.BASIC, router, config, core, @@ -104,12 +108,12 @@ describe('test authentication factory', () => { sessionStorageFactory, logger ); - expect(auth.type).toEqual('basicauth'); + expect(auth.type).toEqual(AuthType.BASIC); }); - test('get basic auth with empty auth type: string array', async () => { + test('get basic auth with empty auth type: string', async () => { const auth = await getAuthenticationHandler( - [''], + '', router, config, core, @@ -117,12 +121,12 @@ describe('test authentication factory', () => { sessionStorageFactory, logger ); - expect(auth.type).toEqual('basicauth'); + expect(auth.type).toEqual(AuthType.BASIC); }); - test('get basic auth with empty auth type: string', async () => { + test('get basic auth with empty auth type: string array', async () => { const auth = await getAuthenticationHandler( - '', + [''], router, config, core, @@ -130,7 +134,7 @@ describe('test authentication factory', () => { sessionStorageFactory, logger ); - expect(auth.type).toEqual('basicauth'); + expect(auth.type).toEqual(AuthType.BASIC); }); test('get jwt auth: string array', async () => { @@ -213,7 +217,7 @@ describe('test authentication factory', () => { test('get saml auth: string array', async () => { const auth = await getAuthenticationHandler( - ['saml'], + [AuthType.SAML], router, config, core, @@ -221,12 +225,12 @@ describe('test authentication factory', () => { sessionStorageFactory, logger ); - expect(auth.type).toEqual('saml'); + expect(auth.type).toEqual(AuthType.SAML); }); test('get saml auth: string', async () => { const auth = await getAuthenticationHandler( - 'saml', + AuthType.SAML, router, config, core, @@ -234,7 +238,7 @@ describe('test authentication factory', () => { sessionStorageFactory, logger ); - expect(auth.type).toEqual('saml'); + expect(auth.type).toEqual(AuthType.SAML); }); test('multiple_auth_enabled is on, get multi auth', async () => { @@ -244,7 +248,7 @@ describe('test authentication factory', () => { }, }; const auth = await getAuthenticationHandler( - ['openid', 'saml', 'basiauth'], + ['openid', AuthType.SAML, AuthType.BASIC], router, config, core, @@ -252,7 +256,7 @@ describe('test authentication factory', () => { sessionStorageFactory, logger ); - expect(auth.type).toEqual(['openid', 'saml', 'basiauth']); + expect(auth.type).toEqual(['openid', AuthType.SAML, AuthType.BASIC]); }); test('multiple_auth_enabled is off, get multi auth', async () => { @@ -263,7 +267,7 @@ describe('test authentication factory', () => { }; try { await getAuthenticationHandler( - ['openid', 'saml', 'basiauth'], + ['openid', AuthType.SAML, AuthType.BASIC], router, config, core, diff --git a/server/auth/types/basic/routes.ts b/server/auth/types/basic/routes.ts index 70ae5ee85..a82c395bd 100755 --- a/server/auth/types/basic/routes.ts +++ b/server/auth/types/basic/routes.ts @@ -30,6 +30,7 @@ import { } from '../../../../common'; import { resolveTenant } from '../../../multitenancy/tenant_resolver'; import { encodeUriQuery } from '../../../../../../src/plugins/opensearch_dashboards_utils/common/url/encode_uri_query'; +import { AuthType } from '../../../../common'; export class BasicAuthRoutes { constructor( @@ -112,7 +113,7 @@ export class BasicAuthRoutes { credentials: { authHeaderValue: `Basic ${encodedCredentials}`, }, - authType: 'basicauth', + authType: AuthType.BASIC, isAnonymousAuth: false, expiryTime: Date.now() + this.config.session.ttl, }; @@ -202,7 +203,7 @@ export class BasicAuthRoutes { this.sessionStorageFactory.asScoped(request).clear(); const sessionStorage: SecuritySessionCookie = { username: user.username, - authType: 'basicauth', + authType: AuthType.BASIC, isAnonymousAuth: true, expiryTime: Date.now() + this.config.session.ttl, }; diff --git a/server/auth/types/saml/saml_auth.ts b/server/auth/types/saml/saml_auth.ts index 5c5c3e426..50801784a 100644 --- a/server/auth/types/saml/saml_auth.ts +++ b/server/auth/types/saml/saml_auth.ts @@ -45,7 +45,7 @@ import { export class SamlAuthentication extends AuthenticationType { public static readonly AUTH_HEADER_NAME = 'authorization'; - public readonly type: string = 'saml'; + public readonly type: string = AuthType.SAML; constructor( config: SecurityPluginConfigType, diff --git a/server/index.ts b/server/index.ts index b4384315a..198b07fe2 100644 --- a/server/index.ts +++ b/server/index.ts @@ -16,14 +16,15 @@ import { schema, TypeOf } from '@osd/config-schema'; import { PluginInitializerContext, PluginConfigDescriptor } from '../../../src/core/server'; import { SecurityPlugin } from './plugin'; +import { AuthType } from '../common'; const validateAuthType = (value: string[]) => { const supportedAuthTypes = [ '', - 'basicauth', + AuthType.BASIC, 'jwt', 'openid', - 'saml', + AuthType.SAML, 'proxy', 'kerberos', 'proxycache', @@ -88,7 +89,7 @@ export const configSchema = schema.object({ if (value.length > 1) { const includeBasicAuth = value.find((element) => { - return element.toLowerCase() === 'basicauth'; + return element.toLowerCase() === AuthType.BASIC; }); if (!includeBasicAuth) { diff --git a/server/routes/auth_type_routes.ts b/server/routes/auth_type_routes.ts index 0b631325e..7c6f4daf1 100644 --- a/server/routes/auth_type_routes.ts +++ b/server/routes/auth_type_routes.ts @@ -15,7 +15,7 @@ import { IRouter } from 'opensearch-dashboards/server'; import { SecurityPluginConfigType } from '..'; - +import { AuthType } from '../../common'; export function defineAuthTypeRoutes(router: IRouter, config: SecurityPluginConfigType) { /** * Auth type API that returns current auth type configured on OpenSearchDashboards Server. @@ -30,7 +30,7 @@ export function defineAuthTypeRoutes(router: IRouter, config: SecurityPluginConf router.get( { path: '/api/authtype', validate: false, options: { authRequired: false } }, async (context, request, response) => { - const authType = config.auth.type || 'basicauth'; + const authType = config.auth.type || AuthType.BASIC; return response.ok({ body: { authtype: authType, diff --git a/test/jest_integration/saml_auth.test.ts b/test/jest_integration/saml_auth.test.ts index 7123baf15..0e963ba68 100644 --- a/test/jest_integration/saml_auth.test.ts +++ b/test/jest_integration/saml_auth.test.ts @@ -25,6 +25,7 @@ import { import wreck from '@hapi/wreck'; import { Builder, By, until } from 'selenium-webdriver'; import { Options } from 'selenium-webdriver/firefox'; +import { AuthType } from '../../common'; describe('start OpenSearch Dashboards server', () => { let root: Root; @@ -73,7 +74,7 @@ describe('start OpenSearch Dashboards server', () => { opensearch_security: { auth: { anonymous_auth_enabled: false, - type: 'saml', + type: AuthType.SAML, }, multitenancy: { enabled: true, @@ -138,7 +139,7 @@ describe('start OpenSearch Dashboards server', () => { order: 5, http_authenticator: { challenge: true, - type: 'saml', + type: AuthType.SAML, config: { idp: { metadata_url: 'http://localhost:7000/metadata', diff --git a/test/jest_integration/saml_multiauth.test.ts b/test/jest_integration/saml_multiauth.test.ts index c29c88085..92defdd1d 100644 --- a/test/jest_integration/saml_multiauth.test.ts +++ b/test/jest_integration/saml_multiauth.test.ts @@ -25,6 +25,7 @@ import { import wreck from '@hapi/wreck'; import { Builder, By, until } from 'selenium-webdriver'; import { Options } from 'selenium-webdriver/firefox'; +import { AuthType } from '../../common'; describe('start OpenSearch Dashboards server', () => { let root: Root; @@ -69,7 +70,7 @@ describe('start OpenSearch Dashboards server', () => { opensearch_security: { auth: { anonymous_auth_enabled: false, - type: ['basicauth', 'saml'], + type: [AuthType.BASIC, AuthType.SAML], multiple_auth_enabled: true, }, multitenancy: { @@ -135,7 +136,7 @@ describe('start OpenSearch Dashboards server', () => { order: 5, http_authenticator: { challenge: true, - type: 'saml', + type: AuthType.SAML, config: { idp: { metadata_url: 'http://localhost:7000/metadata', From 0b7290789d74d5b755317ebf7482ac223dec8992 Mon Sep 17 00:00:00 2001 From: Craig Perkins Date: Tue, 14 Nov 2023 11:04:56 -0500 Subject: [PATCH 09/32] Update babel imports (#1652) Signed-off-by: Craig Perkins --- babel.config.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/babel.config.js b/babel.config.js index ae3ef2bc3..8e9950c03 100644 --- a/babel.config.js +++ b/babel.config.js @@ -26,8 +26,8 @@ module.exports = function (api) { ], plugins: [ [require('@babel/plugin-transform-runtime'), { regenerator: true }], - require('@babel/plugin-proposal-class-properties'), - require('@babel/plugin-proposal-object-rest-spread'), + require('@babel/plugin-transform-class-properties'), + require('@babel/plugin-transform-object-rest-spread'), ], }; } From 31c5a723cb54d8dcb6ab06de4a7a65b1036590e9 Mon Sep 17 00:00:00 2001 From: Ryan Liang <109499885+RyanL1997@users.noreply.github.com> Date: Tue, 14 Nov 2023 10:52:03 -0800 Subject: [PATCH 10/32] Stabilize SAML integration test cases for security dashboard CIs (#1641) Stabilize SAML integration test cases for security dashboard CIs (#1641) --------- Signed-off-by: Ryan Liang --- test/jest_integration/saml_auth.test.ts | 3 ++- test/jest_integration/saml_multiauth.test.ts | 16 +++++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/test/jest_integration/saml_auth.test.ts b/test/jest_integration/saml_auth.test.ts index 0e963ba68..e48635e41 100644 --- a/test/jest_integration/saml_auth.test.ts +++ b/test/jest_integration/saml_auth.test.ts @@ -48,6 +48,7 @@ describe('start OpenSearch Dashboards server', () => { plugins: { scanDirs: [resolve(__dirname, '../..')], }, + home: { disableWelcomeScreen: true }, server: { host: 'localhost', port: 5601, @@ -267,7 +268,7 @@ describe('start OpenSearch Dashboards server', () => { }); it('Login to Dashboard with Hash', async () => { - const urlWithHash = `http://localhost:5601/app/dashboards#/view/7adfa750-4c81-11e8-b3d7-01146121b73d?_g=(filters:!(),refreshInterval:(pause:!f,value:900000),time:(from:now-24h,to:now))&_a=(description:'Analyze%20mock%20flight%20data%20for%20OpenSearch-Air,%20Logstash%20Airways,%20OpenSearch%20Dashboards%20Airlines%20and%20BeatsWest',filters:!(),fullScreenMode:!f,options:(hidePanelTitles:!f,useMargins:!t),query:(language:kuery,query:''),timeRestore:!t,title:'%5BFlights%5D%20Global%20Flight%20Dashboard',viewMode:view)`; + const urlWithHash = `http://localhost:5601/app/security-dashboards-plugin#/getstarted`; const driver = getDriver(browser, options).build(); await driver.manage().deleteAllCookies(); await driver.get(urlWithHash); diff --git a/test/jest_integration/saml_multiauth.test.ts b/test/jest_integration/saml_multiauth.test.ts index 92defdd1d..cd41a52d4 100644 --- a/test/jest_integration/saml_multiauth.test.ts +++ b/test/jest_integration/saml_multiauth.test.ts @@ -44,6 +44,7 @@ describe('start OpenSearch Dashboards server', () => { plugins: { scanDirs: [resolve(__dirname, '../..')], }, + home: { disableWelcomeScreen: true }, server: { host: 'localhost', port: 5601, @@ -236,8 +237,8 @@ describe('start OpenSearch Dashboards server', () => { }); it('Login to Dashboards and resume from nextUrl', async () => { - const urlWithHash = `http://localhost:5601/app/dashboards#/view/7adfa750-4c81-11e8-b3d7-01146121b73d?_g=(filters:!(),refreshInterval:(pause:!f,value:900000),time:(from:now-24h,to:now))&_a=(description:'Analyze%20mock%20flight%20data%20for%20OpenSearch-Air,%20Logstash%20Airways,%20OpenSearch%20Dashboards%20Airlines%20and%20BeatsWest',filters:!(),fullScreenMode:!f,options:(hidePanelTitles:!f,useMargins:!t),query:(language:kuery,query:''),timeRestore:!t,title:'%5BFlights%5D%20Global%20Flight%20Dashboard',viewMode:view)`; - const loginUrlWithNextUrl = `http://localhost:5601/app/login?nextUrl=%2Fapp%2Fdashboards#/view/7adfa750-4c81-11e8-b3d7-01146121b73d?_g=(filters:!(),refreshInterval:(pause:!f,value:900000),time:(from:now-24h,to:now))&_a=(description:'Analyze%20mock%20flight%20data%20for%20OpenSearch-Air,%20Logstash%20Airways,%20OpenSearch%20Dashboards%20Airlines%20and%20BeatsWest',filters:!(),fullScreenMode:!f,options:(hidePanelTitles:!f,useMargins:!t),query:(language:kuery,query:''),timeRestore:!t,title:'%5BFlights%5D%20Global%20Flight%20Dashboard',viewMode:view)`; + const urlWithHash = `http://localhost:5601/app/security-dashboards-plugin#/getstarted`; + const loginUrlWithNextUrl = `http://localhost:5601/app/login?nextUrl=%2Fapp%2Fsecurity-dashboards-plugin#/getstarted`; const driver = getDriver(browser, options).build(); await driver.manage().deleteAllCookies(); await driver.get(loginUrlWithNextUrl); @@ -260,7 +261,7 @@ describe('start OpenSearch Dashboards server', () => { }); it('Login to Dashboards without nextUrl', async () => { - const urlWithoutHash = `http://localhost:5601/app/home`; + const urlWithoutHash = `http://localhost:5601/app/home#/`; const loginUrl = `http://localhost:5601/app/login`; const driver = getDriver(browser, options).build(); await driver.manage().deleteAllCookies(); @@ -274,6 +275,15 @@ describe('start OpenSearch Dashboards server', () => { until.elementsLocated(By.xpath('/html/body/div[1]/div/header/div/div[2]')), 20000 ); + await driver.wait(until.elementsLocated(By.css('img[data-test-subj="defaultLogo"]')), 20000); + await driver.wait( + until.elementsLocated(By.css('section[aria-labelledby="homDataAdd__title"]')), + 20000 + ); + await driver.wait( + until.elementsLocated(By.css('section[aria-labelledby="homDataManage__title"]')), + 20000 + ); const windowHash = await driver.getCurrentUrl(); console.log('windowHash: ' + windowHash); expect(windowHash).toEqual(urlWithoutHash); From 94961bd9a0cb78474c41440b887db23133591966 Mon Sep 17 00:00:00 2001 From: Sam <128482925+samuelcostae@users.noreply.github.com> Date: Fri, 17 Nov 2023 15:13:16 +0000 Subject: [PATCH 11/32] Adds a new tab for Service Accounts (#1502) --------- Signed-off-by: Craig Perkins Signed-off-by: Sam Signed-off-by: Ryan Liang Signed-off-by: Ryan Liang <109499885+RyanL1997@users.noreply.github.com> Signed-off-by: Craig Perkins Signed-off-by: Darshit Chanpura Signed-off-by: Chang Liu Signed-off-by: leanneeliatra Signed-off-by: nursaadat Signed-off-by: Saadat Nursultan Signed-off-by: nurbqq Signed-off-by: nurbqq <106753054+nurbq@users.noreply.github.com> Signed-off-by: vamsi-amazon Signed-off-by: Sirazh Gabdullin Signed-off-by: Jochen Kressin Signed-off-by: Abhi Kalra Signed-off-by: opensearch-ci-bot Signed-off-by: Leanne Lacey-Byrne Signed-off-by: zhichao-aws Signed-off-by: Derek Ho Signed-off-by: leanneeliatra <131779422+leanneeliatra@users.noreply.github.com> Signed-off-by: Hailong Cui Signed-off-by: Peter Nied Signed-off-by: Peter Nied Signed-off-by: Stephen Crawford <65832608+scrawfor99@users.noreply.github.com> Signed-off-by: Darshit Chanpura <35282393+DarshitChanpura@users.noreply.github.com> Co-authored-by: Craig Perkins Co-authored-by: Ryan Liang <109499885+RyanL1997@users.noreply.github.com> Co-authored-by: Darshit Chanpura <35282393+DarshitChanpura@users.noreply.github.com> Co-authored-by: leanneeliatra <131779422+leanneeliatra@users.noreply.github.com> Co-authored-by: Chang Liu Co-authored-by: mattieserver <3049868+mattieserver@users.noreply.github.com> Co-authored-by: Saadat Nursultan <39532643+nurSaadat@users.noreply.github.com> Co-authored-by: nursaadat Co-authored-by: Saadat Nursultan Co-authored-by: Nurbakhyt Sembayev <106753054+nurbq@users.noreply.github.com> Co-authored-by: Stephen Crawford <65832608+scrawfor99@users.noreply.github.com> Co-authored-by: Vamsi Manohar Co-authored-by: Sirazh Gabdullin Co-authored-by: Jochen Kressin <126353411+jochen-kressin@users.noreply.github.com> Co-authored-by: Abhi Kalra <99718513+abhivka7@users.noreply.github.com> Co-authored-by: Abhi Kalra Co-authored-by: opensearch-trigger-bot[bot] <98922864+opensearch-trigger-bot[bot]@users.noreply.github.com> Co-authored-by: opensearch-ci-bot Co-authored-by: zhichao-aws Co-authored-by: Darshit Chanpura Co-authored-by: Derek Ho Co-authored-by: Hailong Cui Co-authored-by: Peter Nied Co-authored-by: Derek Ho --- DEVELOPER_GUIDE.md | 12 +- public/apps/configuration/app-router.tsx | 13 ++ public/apps/configuration/constants.tsx | 2 + .../panels/service-account-list.tsx | 220 ++++++++++++++++++ .../panels/test/service-account-list.test.tsx | 173 ++++++++++++++ .../apps/configuration/panels/user-list.tsx | 6 +- public/apps/configuration/types.ts | 1 + .../utils/internal-user-list-utils.tsx | 31 ++- ...pensearch_security_configuration_plugin.ts | 11 + server/routes/index.ts | 13 +- 10 files changed, 458 insertions(+), 24 deletions(-) create mode 100644 public/apps/configuration/panels/service-account-list.tsx create mode 100644 public/apps/configuration/panels/test/service-account-list.test.tsx diff --git a/DEVELOPER_GUIDE.md b/DEVELOPER_GUIDE.md index 67eb5c354..6c479f4b4 100644 --- a/DEVELOPER_GUIDE.md +++ b/DEVELOPER_GUIDE.md @@ -92,17 +92,9 @@ Next, go to the base directory (`cd ../..`) and run `yarn osd bootstrap` to inst From the base directory, run `yarn start`. This should start dashboard UI successfully. `Cmd+click` the url in the console output (It should look something like `http://0:5601/omf`). Once the page loads, you should be able to log in with user `admin` and password `admin`. -## Testing +## Integration Tests -The security-dashboards-plugin project uses Jest, Cypress and Selenium and makes use of the [OpenSearch Dashboards Functional Test]( https://github.com/opensearch-project/opensearch-dashboards-functional-test) project. - -Make sure you have the OpenSearch and OpenSearch Dashboards running with the Security Plugin and that you can log in to it using a web browser. - -Clone [OpenSearch Dashboards Functional Test]( https://github.com/opensearch-project/opensearch-dashboards-functional-test) in your local machine and follow the instructions in its DEVELOPER_GUIDE.md - -### Integration Tests - -To run selenium based integration tests, download and export the firefox web-driver to your PATH. Also, run `node scripts/build_opensearch_dashboards_platform_plugins.js` or `yarn start` before running the tests. This is essential to generate the bundles. +To run selenium based integration tests, download and export the firefox web-driver to your PATH. Also, run `node scripts/build_opensearch_dashboards_platform_plugins.js` or `yarn start` before running the tests. This is essential to generate the bundles. The integration tests take advantage of [npm "pre" scripts](https://docs.npmjs.com/cli/v9/using-npm/scripts) to run a node based SAML IdP for integration tests related to SAML authentication. This will run a background process that listens on port 7000. diff --git a/public/apps/configuration/app-router.tsx b/public/apps/configuration/app-router.tsx index 6cb97ec0e..a10cec08e 100644 --- a/public/apps/configuration/app-router.tsx +++ b/public/apps/configuration/app-router.tsx @@ -35,6 +35,7 @@ import { RoleEditMappedUser } from './panels/role-mapping/role-edit-mapped-user' import { RoleView } from './panels/role-view/role-view'; import { TenantList } from './panels/tenant-list/tenant-list'; import { UserList } from './panels/user-list'; +import { ServiceAccountList } from './panels/service-account-list'; import { Action, ResourceType, RouteItem, SubAction } from './types'; import { buildHashUrl, buildUrl } from './utils/url-builder'; import { CrossPageToast } from './cross-page-toast'; @@ -54,6 +55,10 @@ const ROUTE_MAP: { [key: string]: RouteItem } = { name: 'Internal users', href: buildUrl(ResourceType.users), }, + [ResourceType.serviceAccounts]: { + name: 'Service Accounts', + href: buildUrl(ResourceType.serviceAccounts), + }, [ResourceType.permissions]: { name: 'Permissions', href: buildUrl(ResourceType.permissions), @@ -85,6 +90,7 @@ const ROUTE_LIST = [ ROUTE_MAP[ResourceType.auth], ROUTE_MAP[ResourceType.roles], ROUTE_MAP[ResourceType.users], + ROUTE_MAP[ResourceType.serviceAccounts], ROUTE_MAP[ResourceType.permissions], ROUTE_MAP[ResourceType.tenants], ROUTE_MAP[ResourceType.auditLogging], @@ -209,6 +215,13 @@ export function AppRouter(props: AppDependencies) { return ; }} /> + { + setGlobalBreadcrumbs(ResourceType.serviceAccounts); + return ; + }} + /> { diff --git a/public/apps/configuration/constants.tsx b/public/apps/configuration/constants.tsx index e789591cd..4dd107a91 100644 --- a/public/apps/configuration/constants.tsx +++ b/public/apps/configuration/constants.tsx @@ -25,6 +25,8 @@ export const API_ENDPOINT_MULTITENANCY = API_PREFIX + '/multitenancy/tenant'; export const API_ENDPOINT_TENANCY_CONFIGS = API_ENDPOINT + '/tenancy/config'; export const API_ENDPOINT_SECURITYCONFIG = API_ENDPOINT + '/securityconfig'; export const API_ENDPOINT_INTERNALUSERS = API_ENDPOINT + '/internalusers'; +export const API_ENDPOINT_INTERNALACCOUNTS = API_ENDPOINT + '/internalaccounts'; +export const API_ENDPOINT_SERVICEACCOUNTS = API_ENDPOINT + '/serviceaccounts'; export const API_ENDPOINT_AUDITLOGGING = API_ENDPOINT + '/audit'; export const API_ENDPOINT_AUDITLOGGING_UPDATE = API_ENDPOINT_AUDITLOGGING + '/config'; export const API_ENDPOINT_PERMISSIONS_INFO = API_PREFIX + '/restapiinfo'; diff --git a/public/apps/configuration/panels/service-account-list.tsx b/public/apps/configuration/panels/service-account-list.tsx new file mode 100644 index 000000000..61c21a9e5 --- /dev/null +++ b/public/apps/configuration/panels/service-account-list.tsx @@ -0,0 +1,220 @@ +/* + * Copyright OpenSearch Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +import { + EuiBadge, + EuiButtonEmpty, + EuiFlexGroup, + EuiFlexItem, + EuiInMemoryTable, + EuiLink, + EuiPageBody, + EuiPageContent, + EuiPageContentHeader, + EuiPageContentHeaderSection, + EuiPageHeader, + EuiText, + EuiTitle, + Query, +} from '@elastic/eui'; +import { Dictionary, difference, isEmpty, map } from 'lodash'; +import React, { useState } from 'react'; +import { getAuthInfo } from '../../../utils/auth-info-utils'; +import { AppDependencies } from '../../types'; +import { API_ENDPOINT_SERVICEACCOUNTS, DocLinks } from '../constants'; +import { Action, ResourceType } from '../types'; +import { EMPTY_FIELD_VALUE } from '../ui-constants'; +import { useContextMenuState } from '../utils/context-menu'; +import { ExternalLink, tableItemsUIProps, truncatedListView } from '../utils/display-utils'; +import { getUserList, InternalUsersListing } from '../utils/internal-user-list-utils'; +import { showTableStatusMessage } from '../utils/loading-spinner-utils'; +import { buildHashUrl } from '../utils/url-builder'; + +export function dictView(items: Dictionary) { + if (isEmpty(items)) { + return EMPTY_FIELD_VALUE; + } + return ( + + {map(items, (v, k) => ( + + {k}: {`"${v}"`} + + ))} + + ); +} + +export function getColumns(currentUsername: string) { + return [ + { + field: 'username', + name: 'Username', + render: (username: string) => ( + <> + {username} + {username === currentUsername && ( + <> +   + Current + + )} + + ), + sortable: true, + }, + { + field: 'backend_roles', + name: 'Backend roles', + render: truncatedListView(tableItemsUIProps), + }, + { + field: 'attributes', + name: 'Attributes', + render: dictView, + truncateText: true, + }, + ]; +} + +export function ServiceAccountList(props: AppDependencies) { + const [userData, setUserData] = React.useState([]); + const [errorFlag, setErrorFlag] = React.useState(false); + const [selection, setSelection] = React.useState([]); + const [currentUsername, setCurrentUsername] = useState(''); + const [loading, setLoading] = useState(false); + const [query, setQuery] = useState(null); + + React.useEffect(() => { + const fetchData = async () => { + try { + setLoading(true); + const userDataPromise = getUserList(props.coreStart.http, ResourceType.serviceAccounts); + setCurrentUsername((await getAuthInfo(props.coreStart.http)).user_name); + setUserData(await userDataPromise); + } catch (e) { + console.log(e); + setErrorFlag(true); + } finally { + setLoading(false); + } + }; + + fetchData(); + }, [props.coreStart.http]); + + const actionsMenuItems = [ + { + window.location.href = buildHashUrl(ResourceType.users, Action.edit, selection[0].username); + }} + disabled={selection.length !== 1} + > + Edit + , + { + window.location.href = buildHashUrl( + ResourceType.users, + Action.duplicate, + selection[0].username + ); + }} + disabled={selection.length !== 1} + > + Duplicate + , + + Export JSON + , + ]; + + const [actionsMenu, closeActionsMenu] = useContextMenuState('Actions', {}, actionsMenuItems); + + return ( + <> + + +

Service accounts

+
+
+ + + + +

+ Service accounts + + {' '} + ({Query.execute(query || '', userData).length}) + +

+
+ + Here you have a list of special accounts that represent services like extensions, + plugins or other third party applications. You can map an account to a role from + Roles + “Manage mapping” + + +
+ + + {actionsMenu} + + +
+ + { + setQuery(arg.query); + return true; + }, + }} + // @ts-ignore + selection={{ onSelectionChange: setSelection }} + sorting + error={ + errorFlag ? 'Load data failed, please check the console log for more details.' : '' + } + message={showTableStatusMessage(loading, userData)} + /> + +
+ + ); +} diff --git a/public/apps/configuration/panels/test/service-account-list.test.tsx b/public/apps/configuration/panels/test/service-account-list.test.tsx new file mode 100644 index 000000000..2ffe595e8 --- /dev/null +++ b/public/apps/configuration/panels/test/service-account-list.test.tsx @@ -0,0 +1,173 @@ +/* + * Copyright OpenSearch Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +import { EuiBadge, EuiText, EuiInMemoryTable } from '@elastic/eui'; +import { shallow } from 'enzyme'; +import React from 'react'; +import { EMPTY_FIELD_VALUE } from '../../ui-constants'; +import { getUserList, InternalUsersListing } from '../../utils/internal-user-list-utils'; +import { dictView, getColumns, ServiceAccountList } from '../service-account-list'; + +jest.mock('../../utils/internal-user-list-utils'); +jest.mock('../../../../utils/auth-info-utils', () => ({ + getAuthInfo: jest.fn().mockReturnValue({ user_name: 'user' }), +})); +jest.mock('../../utils/context-menu', () => ({ + useContextMenuState: jest + .fn() + .mockImplementation((buttonText, buttonProps, children) => [children, jest.fn()]), +})); + +import { getAuthInfo } from '../../../../utils/auth-info-utils'; +import { buildHashUrl } from '../../utils/url-builder'; +import { ResourceType, Action } from '../../types'; + +describe('User list', () => { + describe('dictView', () => { + it('- empty', () => { + const result = dictView({}); + + expect(result).toEqual(EMPTY_FIELD_VALUE); + }); + + it('dictView - non-empty', () => { + const attr1 = 'attr1'; + const attr2 = 'attr2'; + const value1 = 'value1'; + const value2 = 'value2'; + const result = shallow(dictView({ [attr1]: value1, [attr2]: value2 })); + + expect(result.find(EuiText).at(0).prop('children')).toEqual([attr1, ': ', `"${value1}"`]); + expect(result.find(EuiText).at(1).prop('children')).toEqual([attr2, ': ', `"${value2}"`]); + }); + }); + + describe('getColumns', () => { + it('current user', () => { + const columns = getColumns('user1'); + const usernameRenderer = columns[0].render as (usename: string) => JSX.Element; + const Container = (props: { username: string }) => usernameRenderer(props.username); + const result = shallow(); + + expect(result.find(EuiBadge).length).toBe(1); + }); + + it('not current user', () => { + const columns = getColumns('user1'); + const usernameRenderer = columns[0].render as (usename: string) => JSX.Element; + const Container = (props: { username: string }) => usernameRenderer(props.username); + const result = shallow(); + + expect(result.find(EuiBadge).length).toBe(0); + }); + }); + + describe('ServiceAccountList', () => { + const mockCoreStart = { + http: 1, + }; + const setState = jest.fn(); + jest.spyOn(React, 'useState').mockImplementation((initValue) => [initValue, setState]); + + it('render empty', () => { + const component = shallow( + + ); + + expect(component.find(EuiInMemoryTable).prop('items')).toEqual([]); + }); + + it('fetch data', () => { + jest.spyOn(React, 'useEffect').mockImplementationOnce((f) => f()); + shallow( + + ); + + expect(getUserList).toBeCalled(); + expect(getAuthInfo).toBeCalled(); + }); + + it('fetch data error', () => { + jest.spyOn(React, 'useEffect').mockImplementationOnce((f) => f()); + getUserList.mockImplementationOnce(() => { + throw new Error(); + }); + // Hide the error message + jest.spyOn(console, 'log').mockImplementationOnce(() => {}); + shallow( + + ); + + // Expect error flag set to true + expect(setState).toBeCalledWith(true); + }); + }); + + describe('Action menu click', () => { + const mockCoreStart = { + http: { + basePath: { + serverBasePath: '', + }, + }, + }; + let component; + const mockUserListingData: InternalUsersListing = { + username: 'user_1', + attributes: { service: 'true' }, + backend_roles: ['backend_role1'], + }; + beforeEach(() => { + jest.spyOn(React, 'useState').mockImplementation(() => [[mockUserListingData], jest.fn()]); + component = shallow( + + ); + }); + + it('Edit click', () => { + component.find('[data-test-subj="edit"]').simulate('click'); + expect(window.location.hash).toBe( + buildHashUrl(ResourceType.users, Action.edit, mockUserListingData.username) + ); + }); + + it('Duplicate click', () => { + component.find('[data-test-subj="duplicate"]').simulate('click'); + expect(window.location.hash).toBe( + buildHashUrl(ResourceType.users, Action.duplicate, mockUserListingData.username) + ); + }); + }); +}); diff --git a/public/apps/configuration/panels/user-list.tsx b/public/apps/configuration/panels/user-list.tsx index 8cb627f8b..eb369f7ad 100644 --- a/public/apps/configuration/panels/user-list.tsx +++ b/public/apps/configuration/panels/user-list.tsx @@ -107,7 +107,7 @@ export function UserList(props: AppDependencies) { const fetchData = async () => { try { setLoading(true); - const userDataPromise = getUserList(props.coreStart.http); + const userDataPromise = getUserList(props.coreStart.http, ResourceType.users); setCurrentUsername((await getAuthInfo(props.coreStart.http)).user_name); setUserData(await userDataPromise); } catch (e) { @@ -213,7 +213,7 @@ export function UserList(props: AppDependencies) { The Security plugin includes an internal user database. Use this database in place of, or in addition to, an external authentication system such as LDAP server or Active - Directory. You can map an internal user to a role from{' '} + Directory. You can map an user account to a role from{' '} Roles . First, click into the detail page of the role. Then, under “Mapped users”, click “Manage mapping” @@ -224,7 +224,7 @@ export function UserList(props: AppDependencies) { {actionsMenu} - Create internal user + Create user account diff --git a/public/apps/configuration/types.ts b/public/apps/configuration/types.ts index 06ef44369..fd64e1095 100644 --- a/public/apps/configuration/types.ts +++ b/public/apps/configuration/types.ts @@ -22,6 +22,7 @@ export type FieldLevelSecurityMethod = 'exclude' | 'include'; export enum ResourceType { roles = 'roles', users = 'users', + serviceAccounts = 'serviceAccounts', permissions = 'permissions', tenants = 'tenants', tenantsManageTab = 'tenantsManageTab', diff --git a/public/apps/configuration/utils/internal-user-list-utils.tsx b/public/apps/configuration/utils/internal-user-list-utils.tsx index 9a893eeb9..02042e928 100644 --- a/public/apps/configuration/utils/internal-user-list-utils.tsx +++ b/public/apps/configuration/utils/internal-user-list-utils.tsx @@ -15,8 +15,12 @@ import { map } from 'lodash'; import { HttpStart } from '../../../../../../src/core/public'; -import { API_ENDPOINT_INTERNALUSERS } from '../constants'; -import { DataObject, InternalUser, ObjectsMessage } from '../types'; +import { + API_ENDPOINT_INTERNALACCOUNTS, + API_ENDPOINT_INTERNALUSERS, + API_ENDPOINT_SERVICEACCOUNTS, +} from '../constants'; +import { DataObject, InternalUser, ObjectsMessage, ResourceType } from '../types'; import { httpDelete, httpGet } from './request-utils'; import { getResourceUrl } from './resource-utils'; @@ -38,15 +42,26 @@ export async function requestDeleteUsers(http: HttpStart, users: string[]) { } } -async function getUserListRaw(http: HttpStart): Promise> { - return await httpGet>(http, API_ENDPOINT_INTERNALUSERS); +async function getUserListRaw( + http: HttpStart, + userType: string +): Promise> { + let ENDPOINT = API_ENDPOINT_INTERNALACCOUNTS; + if (userType === ResourceType.serviceAccounts) { + ENDPOINT = API_ENDPOINT_SERVICEACCOUNTS; + } + + return await httpGet>(http, ENDPOINT); } -export async function getUserList(http: HttpStart): Promise { - const rawData = await getUserListRaw(http); +export async function getUserList( + http: HttpStart, + userType: string +): Promise { + const rawData = await getUserListRaw(http, userType); return transformUserData(rawData.data); } -export async function fetchUserNameList(http: HttpStart): Promise { - return Object.keys((await getUserListRaw(http)).data); +export async function fetchUserNameList(http: HttpStart, userType: string): Promise { + return Object.keys((await getUserListRaw(http, userType)).data); } diff --git a/server/backend/opensearch_security_configuration_plugin.ts b/server/backend/opensearch_security_configuration_plugin.ts index ff0ccfe21..3b87863b8 100644 --- a/server/backend/opensearch_security_configuration_plugin.ts +++ b/server/backend/opensearch_security_configuration_plugin.ts @@ -59,6 +59,17 @@ export default function (Client: any, config: any, components: any) { }, }); + Client.prototype.opensearch_security.prototype.listInternalAccounts = ca({ + url: { + fmt: '/_plugins/_security/api/internalusers?filterBy=internal', + }, + }); + Client.prototype.opensearch_security.prototype.listServiceAccounts = ca({ + url: { + fmt: '/_plugins/_security/api/internalusers?filterBy=service', + }, + }); + /** * Creates a Security resource instance. * diff --git a/server/routes/index.ts b/server/routes/index.ts index 8331c1200..ad3dfbd58 100644 --- a/server/routes/index.ts +++ b/server/routes/index.ts @@ -21,6 +21,7 @@ import { OpenSearchDashboardsResponseFactory, } from 'opensearch-dashboards/server'; import { API_PREFIX, CONFIGURATION_API_PREFIX, isValidResourceName } from '../../common'; +import { ResourceType } from '../../public/apps/configuration/types'; // TODO: consider to extract entity CRUD operations and put it into a client class export function defineRoutes(router: IRouter) { @@ -248,9 +249,15 @@ export function defineRoutes(router: IRouter) { const client = context.security_plugin.esClient.asScoped(request); let esResp; try { - esResp = await client.callAsCurrentUser('opensearch_security.listResource', { - resourceName: request.params.resourceName, - }); + if (request.params.resourceName === ResourceType.serviceAccounts.toLowerCase()) { + esResp = await client.callAsCurrentUser('opensearch_security.listServiceAccounts'); + } else if (request.params.resourceName === 'internalaccounts') { + esResp = await client.callAsCurrentUser('opensearch_security.listInternalAccounts'); + } else { + esResp = await client.callAsCurrentUser('opensearch_security.listResource', { + resourceName: request.params.resourceName, + }); + } return response.ok({ body: { total: Object.keys(esResp).length, From fe7bad6860464ca8f15c6682a9e5b7b53783a845 Mon Sep 17 00:00:00 2001 From: Darshit Chanpura <35282393+DarshitChanpura@users.noreply.github.com> Date: Fri, 17 Nov 2023 13:54:41 -0500 Subject: [PATCH 12/32] Passes `-t` flag to demo-config script in the setup script step to skip password validation (#1656) Signed-off-by: Darshit Chanpura --- .github/actions/download-plugin/action.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/actions/download-plugin/action.yml b/.github/actions/download-plugin/action.yml index d50cfffd4..c97e2e9c1 100644 --- a/.github/actions/download-plugin/action.yml +++ b/.github/actions/download-plugin/action.yml @@ -30,7 +30,7 @@ runs: run: | cat > setup.sh <<'EOF' chmod +x ./opensearch-${{ inputs.opensearch-version}}-SNAPSHOT/plugins/${{ inputs.plugin-name }}/tools/install_demo_configuration.sh - /bin/bash -c "yes | ./opensearch-${{ inputs.opensearch-version}}-SNAPSHOT/plugins/${{ inputs.plugin-name }}/tools/install_demo_configuration.sh" + /bin/bash -c "yes | ./opensearch-${{ inputs.opensearch-version}}-SNAPSHOT/plugins/${{ inputs.plugin-name }}/tools/install_demo_configuration.sh -t" echo "plugins.security.unsupported.restapi.allow_securityconfig_modification: true" >> ./opensearch-${{ inputs.opensearch-version }}-SNAPSHOT/config/opensearch.yml echo "cluster.routing.allocation.disk.threshold_enabled: false" >> ./opensearch-${{ inputs.opensearch-version }}-SNAPSHOT/config/opensearch.yml EOF @@ -40,7 +40,7 @@ runs: if: ${{ runner.os == 'Windows' }} run: | New-Item .\setup.bat -type file - Set-Content .\setup.bat -Value "powershell.exe -noexit -command `".\opensearch-${{ inputs.opensearch-version}}-SNAPSHOT\plugins\${{ inputs.plugin-name }}\tools\install_demo_configuration.bat -y -i -c`"" + Set-Content .\setup.bat -Value "powershell.exe -noexit -command `".\opensearch-${{ inputs.opensearch-version}}-SNAPSHOT\plugins\${{ inputs.plugin-name }}\tools\install_demo_configuration.bat -y -i -c -t`"" Add-Content -Path .\setup.bat -Value "echo plugins.security.unsupported.restapi.allow_securityconfig_modification: true >> .\opensearch-${{ inputs.opensearch-version}}-SNAPSHOT\config\opensearch.yml" Add-Content -Path .\setup.bat -Value "echo cluster.routing.allocation.disk.threshold_enabled: false >> .\opensearch-${{ inputs.opensearch-version}}-SNAPSHOT\config\opensearch.yml" Get-Content .\setup.bat From d5a6626b913c7ec784c0f19cfde528b9a91445ed Mon Sep 17 00:00:00 2001 From: Michael Froh Date: Tue, 21 Nov 2023 16:53:46 +0000 Subject: [PATCH 13/32] Add search pipeline action permissions (#1661) Search pipelines have been generally available since OpenSearch 2.9. We should make it easy to manage permissions for search pipeline CRUD operations. Signed-off-by: Michael Froh --- public/apps/configuration/constants.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/public/apps/configuration/constants.tsx b/public/apps/configuration/constants.tsx index 4dd107a91..84d3fb75a 100644 --- a/public/apps/configuration/constants.tsx +++ b/public/apps/configuration/constants.tsx @@ -182,6 +182,9 @@ export const CLUSTER_PERMISSIONS: string[] = [ 'cluster:admin/script/put', 'cluster:admin/script_context/get', 'cluster:admin/script_language/get', + 'cluster:admin/search/pipeline/delete', + 'cluster:admin/search/pipeline/get', + 'cluster:admin/search/pipeline/put', 'cluster:admin/settings/update', 'cluster:admin/snapshot/create', 'cluster:admin/snapshot/clone', From cfc83dd94eea02b5738bf607dd9866308814f2fc Mon Sep 17 00:00:00 2001 From: jakubp-eliatra <126599757+jakubp-eliatra@users.noreply.github.com> Date: Tue, 28 Nov 2023 18:29:20 +0100 Subject: [PATCH 14/32] Show controls as read only based on tenant permissions (#1472) Signed-off-by: Kajetan Nobel Signed-off-by: Kajetan Nobel Co-authored-by: Stephen Crawford <65832608+scrawfor99@users.noreply.github.com> Co-authored-by: Darshit Chanpura <35282393+DarshitChanpura@users.noreply.github.com> Co-authored-by: Peter Nied Co-authored-by: Peter Nied --- server/auth/types/authentication_type.ts | 10 +- server/plugin.ts | 18 +- server/readonly/readonly_service.test.ts | 212 +++++++++++++++++++++++ server/readonly/readonly_service.ts | 119 +++++++++++++ 4 files changed, 349 insertions(+), 10 deletions(-) create mode 100644 server/readonly/readonly_service.test.ts create mode 100644 server/readonly/readonly_service.ts diff --git a/server/auth/types/authentication_type.ts b/server/auth/types/authentication_type.ts index 56ec21463..1ffeb76cf 100755 --- a/server/auth/types/authentication_type.ts +++ b/server/auth/types/authentication_type.ts @@ -37,6 +37,11 @@ export interface IAuthenticationType { type: string; authHandler: AuthenticationHandler; init: () => Promise; + requestIncludesAuthInfo(request: OpenSearchDashboardsRequest): boolean; + buildAuthHeaderFromCookie( + cookie: SecuritySessionCookie, + request: OpenSearchDashboardsRequest + ): any; } export type IAuthHandlerConstructor = new ( @@ -267,7 +272,6 @@ export abstract class AuthenticationType implements IAuthenticationType { } // abstract functions for concrete auth types to implement - public abstract requestIncludesAuthInfo(request: OpenSearchDashboardsRequest): boolean; public abstract getAdditionalAuthHeader(request: OpenSearchDashboardsRequest): Promise; public abstract getCookie( request: OpenSearchDashboardsRequest, @@ -282,9 +286,5 @@ export abstract class AuthenticationType implements IAuthenticationType { response: LifecycleResponseFactory, toolkit: AuthToolkit ): IOpenSearchDashboardsResponse | AuthResult; - public abstract buildAuthHeaderFromCookie( - cookie: SecuritySessionCookie, - request: OpenSearchDashboardsRequest - ): any; public abstract init(): Promise; } diff --git a/server/plugin.ts b/server/plugin.ts index c6aec6e58..0f266c1fe 100644 --- a/server/plugin.ts +++ b/server/plugin.ts @@ -15,7 +15,6 @@ import { first } from 'rxjs/operators'; import { Observable } from 'rxjs'; -import { ResponseObject } from '@hapi/hapi'; import { PluginInitializerContext, CoreSetup, @@ -39,16 +38,14 @@ import { ISavedObjectTypeRegistry, } from '../../../src/core/server/saved_objects'; import { setupIndexTemplate, migrateTenantIndices } from './multitenancy/tenant_index'; -import { - IAuthenticationType, - OpenSearchDashboardsAuthState, -} from './auth/types/authentication_type'; +import { IAuthenticationType } from './auth/types/authentication_type'; import { getAuthenticationHandler } from './auth/auth_handler_factory'; import { setupMultitenantRoutes } from './multitenancy/routes'; import { defineAuthTypeRoutes } from './routes/auth_type_routes'; import { createMigrationOpenSearchClient } from '../../../src/core/server/saved_objects/migrations/core'; import { SecuritySavedObjectsClientWrapper } from './saved_objects/saved_objects_wrapper'; import { addTenantParameterToResolvedShortLink } from './multitenancy/tenant_resolver'; +import { ReadonlyService } from './readonly/readonly_service'; export interface SecurityPluginRequestContext { logger: Logger; @@ -138,6 +135,7 @@ export class SecurityPlugin implements Plugin = {}): SecuritySessionCookie => + Object.assign( + { + username: 'test', + credentials: { + authHeaderValue: 'Basic cmVhZG9ubHk6Z2FzZGN4ejRRIQ==', + }, + authType: 'basicauth', + isAnonymousAuth: false, + tenant: '__user__', + }, + data + ); + +const mockEsClient = (): jest.Mocked => { + return { + callAsInternalUser: jest.fn(), + asScoped: jest.fn(), + }; +}; + +const mockAuthInfo = (data: Partial = {}): OpenSearchAuthInfo => + Object.assign( + { + user: '', + user_name: 'admin', + user_requested_tenant: PRIVATE_TENANT_SYMBOL, + remote_address: '127.0.0.1', + backend_roles: ['admin'], + custom_attribute_names: [], + roles: ['own_index', 'all_access'], + tenants: { + admin_tenant: true, + admin: true, + }, + principal: null, + peer_certificates: '0', + sso_logout_url: null, + }, + data + ); + +const mockDashboardsInfo = (data = {}) => + Object.assign( + { + user_name: 'admin', + multitenancy_enabled: true, + }, + data + ); + +const getService = ( + cookie: SecuritySessionCookie = mockCookie(), + authInfo: OpenSearchAuthInfo = mockAuthInfo(), + dashboardsInfo = mockDashboardsInfo() +) => { + const logger = loggerMock.create(); + + const securityClient = new SecurityClient(mockEsClient()); + securityClient.authinfo = jest.fn().mockReturnValue(authInfo); + securityClient.dashboardsinfo = jest.fn().mockReturnValue(dashboardsInfo); + + // @ts-ignore mock auth + const auth = new BasicAuthentication(); + auth.requestIncludesAuthInfo = jest.fn().mockReturnValue(true); + + const securitySessionStorageFactory = sessionStorageMock.createFactory(); + securitySessionStorageFactory.asScoped = jest.fn().mockReturnValue({ + get: jest.fn().mockResolvedValue(cookie), + }); + + const config = { + multitenancy: { + enabled: true, + }, + } as SecurityPluginConfigType; + + return new ReadonlyService(logger, securityClient, auth, securitySessionStorageFactory, config); +}; + +describe('checks isAnonymousPage', () => { + const service = getService(); + + it.each([ + // Missing referer header + [ + { + path: '/api/core/capabilities', + headers: {}, + auth: { + isAuthenticated: false, + mode: 'optional', + }, + }, + false, + ], + // Referer with not anynoumous page + [ + { + headers: { + referer: 'https://localhost/app/management/opensearch-dashboards/indexPatterns', + }, + }, + false, + ], + // Referer with anynoumous page + [ + { + path: '/app/login', + headers: { + referer: 'https://localhost/app/login', + }, + routeAuthRequired: false, + }, + true, + ], + ])('%j returns result %s', (requestData, expectedResult) => { + const request = httpServerMock.createOpenSearchDashboardsRequest(requestData); + expect(service.isAnonymousPage(request)).toEqual(expectedResult); + }); +}); + +describe('checks isReadOnlyTenant', () => { + const service = getService(); + + it.each([ + // returns false with private global tenant + [mockAuthInfo({ user_requested_tenant: PRIVATE_TENANT_SYMBOL }), false], + // returns false when has requested tenant but it's read and write + [ + mockAuthInfo({ + user_requested_tenant: 'readonly_tenant', + tenants: { + readonly_tenant: true, + }, + }), + false, + ], + // returns true when has requested tenant and it's read only + [ + mockAuthInfo({ + user_requested_tenant: 'readonly_tenant', + tenants: { + readonly_tenant: false, + }, + }), + true, + ], + ])('%j returns result %s', (authInfo, expectedResult) => { + expect(service.isReadOnlyTenant(authInfo)).toBe(expectedResult); + }); +}); + +describe('checks isReadonly', () => { + it('calls isAnonymousPage', async () => { + const service = getService(); + service.isAnonymousPage = jest.fn(() => true); + await service.isReadonly(httpServerMock.createOpenSearchDashboardsRequest()); + expect(service.isAnonymousPage).toBeCalled(); + }); + it('calls isReadOnlyTenant with correct authinfo', async () => { + const cookie = mockCookie({ tenant: 'readonly_tenant' }); + const authInfo = mockAuthInfo({ + user_requested_tenant: 'readonly_tenant', + tenants: { + readonly_tenant: false, + }, + }); + + const service = getService(cookie, authInfo); + service.isAnonymousPage = jest.fn(() => false); + + const result = await service.isReadonly(httpServerMock.createOpenSearchDashboardsRequest()); + expect(result).toBeTruthy(); + }); + it('calls dashboardInfo and checks if multitenancy is enabled', async () => { + const dashboardsInfo = mockDashboardsInfo({ multitenancy_enabled: false }); + const service = getService(mockCookie(), mockAuthInfo(), dashboardsInfo); + service.isAnonymousPage = jest.fn(() => false); + + const result = await service.isReadonly(httpServerMock.createOpenSearchDashboardsRequest()); + expect(result).toBeFalsy(); + }); +}); diff --git a/server/readonly/readonly_service.ts b/server/readonly/readonly_service.ts new file mode 100644 index 000000000..6e690b5f7 --- /dev/null +++ b/server/readonly/readonly_service.ts @@ -0,0 +1,119 @@ +/* + * Copyright OpenSearch Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +import { URL } from 'url'; +import { + Logger, + OpenSearchDashboardsRequest, + SessionStorageFactory, +} from '../../../../src/core/server'; +import { + globalTenantName, + isPrivateTenant, + LOGIN_PAGE_URI, + CUSTOM_ERROR_PAGE_URI, +} from '../../common'; +import { SecurityClient } from '../backend/opensearch_security_client'; +import { IAuthenticationType, OpenSearchAuthInfo } from '../auth/types/authentication_type'; +import { SecuritySessionCookie } from '../session/security_cookie'; +import { SecurityPluginConfigType } from '../index'; +import { ReadonlyService as BaseReadonlyService } from '../../../../src/core/server/security/readonly_service'; + +export class ReadonlyService extends BaseReadonlyService { + protected static readonly ROUTES_TO_IGNORE: string[] = [LOGIN_PAGE_URI, CUSTOM_ERROR_PAGE_URI]; + + private readonly logger: Logger; + private readonly securityClient: SecurityClient; + private readonly auth: IAuthenticationType; + private readonly securitySessionStorageFactory: SessionStorageFactory; + private readonly config: SecurityPluginConfigType; + + constructor( + logger: Logger, + securityClient: SecurityClient, + auth: IAuthenticationType, + securitySessionStorageFactory: SessionStorageFactory, + config: SecurityPluginConfigType + ) { + super(); + this.logger = logger; + this.securityClient = securityClient; + this.auth = auth; + this.securitySessionStorageFactory = securitySessionStorageFactory; + this.config = config; + } + + isAnonymousPage(request: OpenSearchDashboardsRequest) { + if (typeof request.route.options.authRequired === 'boolean') { + return !request.route.options.authRequired; + } + + if (!request.headers || !request.headers.referer) { + return false; + } + + const url = new URL(request.headers.referer as string); + return ReadonlyService.ROUTES_TO_IGNORE.some((path) => url.pathname?.includes(path)); + } + + isReadOnlyTenant(authInfo: OpenSearchAuthInfo): boolean { + const currentTenant = authInfo.user_requested_tenant || globalTenantName; + + // private tenants are isolated to individual users that always have read/write permissions + if (isPrivateTenant(currentTenant)) { + return false; + } + + const readWriteAccess = authInfo.tenants[currentTenant]; + return !readWriteAccess; + } + + async isReadonly(request: OpenSearchDashboardsRequest): Promise { + if (!this.config?.multitenancy.enabled) { + return false; + } + + // omit for anonymous pages to avoid authentication errors + if (this.isAnonymousPage(request)) { + return false; + } + + try { + const cookie = await this.securitySessionStorageFactory.asScoped(request).get(); + let headers = request.headers; + + if (!this.auth.requestIncludesAuthInfo(request) && cookie) { + headers = this.auth.buildAuthHeaderFromCookie(cookie, request); + } + + const dashboardsInfo = await this.securityClient.dashboardsinfo(request, headers); + + if (!dashboardsInfo.multitenancy_enabled) { + return false; + } + + const authInfo = await this.securityClient.authinfo(request, headers); + + if (!authInfo.user_requested_tenant && cookie) { + authInfo.user_requested_tenant = cookie.tenant; + } + + return authInfo && this.isReadOnlyTenant(authInfo); + } catch (error: any) { + this.logger.error(`Failed to resolve if it's a readonly tenant: ${error.stack}`); + return false; + } + } +} From 8f1334edc5d6114e14a9220e377c5da887e3e8e1 Mon Sep 17 00:00:00 2001 From: leanneeliatra <131779422+leanneeliatra@users.noreply.github.com> Date: Tue, 28 Nov 2023 19:14:32 +0000 Subject: [PATCH 15/32] Fix copy link issue in Safari (#1633) Signed-off-by: leanne.laceybyrne@eliatra.com Signed-off-by: leanneeliatra Signed-off-by: leanneeliatra <131779422+leanneeliatra@users.noreply.github.com> --- public/services/shared-link.ts | 101 ++++++++++++---------- public/services/test/shared-link.test.ts | 102 +++++++++++++++++++++++ 2 files changed, 161 insertions(+), 42 deletions(-) create mode 100644 public/services/test/shared-link.test.ts diff --git a/public/services/shared-link.ts b/public/services/shared-link.ts index 738c662a7..4a078735e 100644 --- a/public/services/shared-link.ts +++ b/public/services/shared-link.ts @@ -12,15 +12,16 @@ * express or implied. See the License for the specific language governing * permissions and limitations under the License. */ - import { parse } from 'url'; import { CoreStart } from 'opensearch-dashboards/public'; import { API_ENDPOINT_MULTITENANCY } from '../apps/configuration/constants'; export async function addTenantToShareURL(core: CoreStart) { let tenant = ''; + try { tenant = await core.http.get(API_ENDPOINT_MULTITENANCY); + if (!tenant) { tenant = 'global'; } else if (tenant === '__user__') { @@ -30,70 +31,86 @@ export async function addTenantToShareURL(core: CoreStart) { console.log(`failed to get user tenant: ${error}`); return; } - // Add the tenant to URLs copied from the share panel + document.addEventListener('copy', (event) => { - const shareButton = document.querySelector('[data-share-url]'); - const target = document.querySelector('body > span'); - // The copy event listens to Cmd + C too, so we need to make sure - // that we're actually copied something via the share panel - if ( - shareButton && - target && - shareButton.getAttribute('data-share-url') === target.textContent - ) { - const originalValue = target.textContent; - let urlPart = originalValue; - - // We need to figure out where in the value to add the tenant. - // Since OpenSearchDashboards sometimes adds values that aren't in the current location/url, - // we need to use the actual input values to do a sanity check. - try { - // For the iFrame urls we need to parse out the src - if (originalValue && originalValue.toLowerCase().indexOf(']*src="([^"]*)"/i; - const match = regex.exec(originalValue); - if (match) { - urlPart = match[1]; // Contains the matched src, [0] contains the string where the match was found - } - } + processCopyEvent(tenant); + }); +} - const newValue = addTenantToURL(urlPart!, originalValue!, tenant); +export function processCopyEvent(userRequestedTenant: string) { + const shareButton = document.querySelector('[data-share-url]') as any; + const target = document.querySelector('body > span'); - if (newValue !== originalValue) { - target.textContent = newValue; + // The copy event listens to Cmd + C too, so we need to make sure + // that we're actually copied something via the share panel + if (shareButton && target && shareButton.getAttribute('data-share-url') === target.textContent) { + const originalValue = target.textContent; + let urlPart = originalValue; + + // We need to figure out where in the value to add the tenant. + // Since OpenSearchDashboards sometimes adds values that aren't in the current location/url, + // we need to use the actual input values to do a sanity check. + try { + // For the iFrame urls we need to parse out the src + if (originalValue && originalValue.toLowerCase().indexOf(']*src="([^"]*)"/i; + const match = regex.exec(originalValue); + if (match) { + urlPart = match[1]; // Contains the matched src, [0] contains the string where the match was found } - } catch (error) { - // Probably wasn't an url, so we just ignore this } + + updateClipboard(urlPart, originalValue, userRequestedTenant); + } catch (error) { + // Probably wasn't an url, so we just ignore this } - }); + } } -function addTenantToURL( - url: string, +export function updateClipboard( + urlPart: string, originalValue: string | undefined, - userRequestedTenant: string + tenant: string ) { - const tenantKey = 'security_tenant'; - const tenantKeyAndValue = tenantKey + '=' + encodeURIComponent(userRequestedTenant); + const shareButton = document.querySelector('[data-share-url]') as any; + const target = document.querySelector('body > span'); if (!originalValue) { - originalValue = url; + originalValue = urlPart; } - const { host, pathname, search } = parse(url); + const { host, pathname, search } = parse(urlPart); const queryDelimiter = !search ? '?' : '&'; // The url parser returns null if the search is empty. Change that to an empty // string so that we can use it to build the values later - if (search && search.toLowerCase().indexOf(tenantKey) > -1) { + if (search && search.toLowerCase().indexOf('security_tenant') > -1) { // If we for some reason already have a tenant in the URL we skip any updates return originalValue; } // A helper for finding the part in the string that we want to extend/replace const valueToReplace = host! + pathname! + (search || ''); - const replaceWith = valueToReplace + queryDelimiter + tenantKeyAndValue; + const replaceWith = + valueToReplace + queryDelimiter + 'security_tenant=' + encodeURIComponent(tenant); + + setClipboardAndTarget(shareButton, target, replaceWith, originalValue); +} - return originalValue.replace(valueToReplace, replaceWith); +export function setClipboardAndTarget( + shareButton: any, + target: any, + newValue: string, + originalValue: string +) { + const range = document.createRange() as any; + const referenceNode = document.getElementsByTagName('span').item(0); + + range.selectNode(referenceNode); + shareButton.removeAllRanges(); + shareButton.addRange(range); + + if (newValue !== originalValue) { + target.textContent = newValue; + } } diff --git a/public/services/test/shared-link.test.ts b/public/services/test/shared-link.test.ts new file mode 100644 index 000000000..8849b2f76 --- /dev/null +++ b/public/services/test/shared-link.test.ts @@ -0,0 +1,102 @@ +/* + * Copyright OpenSearch Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ +// Import necessary modules and dependencies +import { API_ENDPOINT_MULTITENANCY } from '../../apps/configuration/constants.tsx'; +import { + addTenantToShareURL, + processCopyEvent, + setClipboardAndTarget, + updateClipboard, +} from '../shared-link.ts'; + +describe('addTenantToShareURL function', () => { + it('should add a listener for copy events', () => { + const coreMock: any = { + http: { + get: jest.fn().mockResolvedValue('mocked-tenant'), + }, + }; + + jest.spyOn(document, 'addEventListener').mockImplementation((event, callback) => { + if (event === 'copy') { + callback(new Event('copy')); + expect(coreMock.http.get).toHaveBeenCalledWith(API_ENDPOINT_MULTITENANCY); + } + }); + addTenantToShareURL(coreMock); + }); +}); + +describe('processCopyEvent function', () => { + it('should update the clipboard and target text content', () => { + const shareButtonMock: any = { + getAttribute: jest.fn().mockReturnValue('mocked-share-url'), + }; + + const targetMock: any = { + textContent: 'mocked-text-content', + }; + + jest.spyOn(document, 'querySelector').mockImplementation((selector) => { + if (selector === '[data-share-url]') { + return shareButtonMock; + } else if (selector === 'body > span') { + return targetMock; + } + }); + + jest.spyOn(document, 'createRange').mockReturnValue({ + selectNode: jest.fn(), + } as any); + + processCopyEvent('mocked-tenant'); + }); +}); + +describe('updateClipboard function', () => { + it('should update the clipboard and target text content', () => { + const shareButtonMock: any = { + getAttribute: jest.fn().mockReturnValue('mocked-share-url'), + removeAllRanges: jest.fn(), + addRange: jest.fn(), + }; + + const targetMock: any = { + textContent: 'mocked-text-content', + }; + + jest.spyOn(document, 'querySelector').mockImplementation((selector) => { + if (selector === '[data-share-url]') { + return shareButtonMock; + } else if (selector === 'body > span') { + return targetMock; + } + }); + updateClipboard('mocked-url-part', 'mocked-original-value', 'mocked-tenant'); + }); +}); +describe('setClipboardAndTarget function', () => { + it('should set clipboard and target correctly', () => { + const shareButtonMock: any = { + removeAllRanges: jest.fn(), + addRange: jest.fn(), + }; + + const targetMock: any = { + textContent: 'mocked-text-content', + }; + setClipboardAndTarget(shareButtonMock, targetMock, 'mocked-new-value', 'mocked-original-value'); + }); +}); From 5cf1748446d5f7b914618d4e91ebaf671c8afc27 Mon Sep 17 00:00:00 2001 From: Sam <128482925+samuelcostae@users.noreply.github.com> Date: Wed, 29 Nov 2023 15:18:41 +0000 Subject: [PATCH 16/32] Adds openid parameters (#1637) Signed-off-by: Sam Co-authored-by: Darshit Chanpura <35282393+DarshitChanpura@users.noreply.github.com> --- package.json | 2 +- server/auth/types/openid/helper.test.ts | 50 ++++++++++++++++++++++++- server/auth/types/openid/helper.ts | 14 +++++++ server/auth/types/openid/routes.ts | 4 +- server/index.ts | 1 + 5 files changed, 68 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 6ae13f2c1..e3993e5a5 100644 --- a/package.json +++ b/package.json @@ -39,4 +39,4 @@ "resolutions": { "selenium-webdriver": "4.10.0" } -} \ No newline at end of file +} diff --git a/server/auth/types/openid/helper.test.ts b/server/auth/types/openid/helper.test.ts index 3a125a2bf..f5cce4af0 100644 --- a/server/auth/types/openid/helper.test.ts +++ b/server/auth/types/openid/helper.test.ts @@ -13,7 +13,13 @@ * permissions and limitations under the License. */ -import { composeLogoutUrl, getExpirationDate, getRootUrl, getNextUrl } from './helper'; +import { + composeLogoutUrl, + getExpirationDate, + getRootUrl, + getNextUrl, + includeAdditionalParameters, +} from './helper'; describe('test OIDC helper utility', () => { test('test compose logout url', () => { @@ -56,6 +62,48 @@ describe('test OIDC helper utility', () => { ); }); + test('test include additional parameters in query', () => { + const contextMock = { security_plugin: { logger: { warn: jest.fn() } } }; + + const query = { existingKey: 'value' }; + const constQueryModified = { existingKey: 'value', ping: 'pong', acr_values: '1' }; + const config = { + openid: { + enabled: true, + client_secret: '', + additional_parameters: { + ping: 'pong', + acr_values: '1', + existingKey: 'foobar', + }, + }, + }; + + includeAdditionalParameters(query, contextMock, config); + expect(query).toEqual(constQueryModified); + expect(contextMock.security_plugin.logger.warn).toHaveBeenCalledTimes(1); + expect(contextMock.security_plugin.logger.warn).toHaveBeenCalledWith( + "Additional parameter in OpenID config 'existingKey' was ignored as it would overwrite existing parameters" + ); + }); + + test('test include additional parameters in query when no additional parameters specified', () => { + const contextMock = { security_plugin: { logger: { warn: jest.fn() } } }; + + const query = { existingKey: 'value' }; + const constQueryModified = { existingKey: 'value' }; + const config = { + openid: { + enabled: true, + client_secret: '', + }, + }; + + includeAdditionalParameters(query, contextMock, config); + expect(query).toEqual(constQueryModified); + expect(contextMock.security_plugin.logger.warn).toHaveBeenCalledTimes(0); + }); + test('test root url when trusted header unset', () => { const config = { openid: { diff --git a/server/auth/types/openid/helper.ts b/server/auth/types/openid/helper.ts index 9839175ca..dcea8c7a2 100644 --- a/server/auth/types/openid/helper.ts +++ b/server/auth/types/openid/helper.ts @@ -144,3 +144,17 @@ export function getExpirationDate(tokenResponse: TokenResponse | undefined) { return Date.now() + tokenResponse.expiresIn! * 1000; } } + +export function includeAdditionalParameters(query: any, context, config) { + if (config.openid?.additional_parameters) { + for (const [key, value] of Object.entries(config.openid?.additional_parameters)) { + if (query[key] == null) { + query[key] = value; + } else { + context.security_plugin.logger.warn( + `Additional parameter in OpenID config '${key}' was ignored as it would overwrite existing parameters` + ); + } + } + } +} diff --git a/server/auth/types/openid/routes.ts b/server/auth/types/openid/routes.ts index b598dd1a8..46c0d6c88 100644 --- a/server/auth/types/openid/routes.ts +++ b/server/auth/types/openid/routes.ts @@ -34,6 +34,7 @@ import { composeLogoutUrl, getNextUrl, getExpirationDate, + includeAdditionalParameters, } from './helper'; import { validateNextUrl } from '../../../utils/next_url'; import { @@ -127,6 +128,7 @@ export class OpenIdAuthRoutes { state: nonce, scope: this.openIdAuthConfig.scope, }; + includeAdditionalParameters(query, context, this.config); const queryString = stringify(query); const location = `${this.openIdAuthConfig.authorizationEndpoint}?${queryString}`; const cookie: SecuritySessionCookie = { @@ -173,7 +175,7 @@ export class OpenIdAuthRoutes { client_id: clientId, client_secret: clientSecret, }; - + includeAdditionalParameters(query, context, this.config); try { const tokenResponse = await callTokenEndpoint( this.openIdAuthConfig.tokenEndpoint!, diff --git a/server/index.ts b/server/index.ts index 198b07fe2..c1af7fa16 100644 --- a/server/index.ts +++ b/server/index.ts @@ -181,6 +181,7 @@ export const configSchema = schema.object({ verify_hostnames: schema.boolean({ defaultValue: true }), refresh_tokens: schema.boolean({ defaultValue: true }), trust_dynamic_headers: schema.boolean({ defaultValue: false }), + additional_parameters: schema.maybe(schema.any({ defaultValue: null })), extra_storage: schema.object({ cookie_prefix: schema.string({ defaultValue: 'security_authentication_oidc', From d8633681c5b84bb20b6c0e5fd6faf500270cf94e Mon Sep 17 00:00:00 2001 From: Ryan Liang <109499885+RyanL1997@users.noreply.github.com> Date: Wed, 29 Nov 2023 11:44:07 -0800 Subject: [PATCH 17/32] Cypress13 testing frame work for OIDC and SAML (#1579) * Cypress13 testing frame work for OIDC and SAML --------- Signed-off-by: Ryan Liang --- .eslintignore | 1 + .eslintrc.js | 32 +- .github/workflows/cypress-test-oidc-e2e.yml | 256 ++++++++++++ .github/workflows/cypress-test-saml-e2e.yml | 216 ++++++++++ .gitignore | 2 + cypress.config.js | 35 ++ package.json | 5 + test/cypress/e2e/oidc/oidc_auth_test.spec.js | 125 ++++++ test/cypress/e2e/saml/saml_auth_test.spec.js | 121 ++++++ .../fixtures/saml/samlUserRoleMappiing.json | 4 + test/cypress/support/commands.js | 80 ++++ test/cypress/support/constants.js | 42 ++ test/cypress/support/e2e.js | 36 ++ test/cypress/support/index.d.ts | 55 +++ test/jest_integration/saml_auth.test.ts | 374 ------------------ 15 files changed, 1000 insertions(+), 384 deletions(-) create mode 100644 .github/workflows/cypress-test-oidc-e2e.yml create mode 100644 .github/workflows/cypress-test-saml-e2e.yml create mode 100644 cypress.config.js create mode 100644 test/cypress/e2e/oidc/oidc_auth_test.spec.js create mode 100644 test/cypress/e2e/saml/saml_auth_test.spec.js create mode 100644 test/cypress/fixtures/saml/samlUserRoleMappiing.json create mode 100644 test/cypress/support/commands.js create mode 100644 test/cypress/support/constants.js create mode 100644 test/cypress/support/e2e.js create mode 100644 test/cypress/support/index.d.ts delete mode 100644 test/jest_integration/saml_auth.test.ts diff --git a/.eslintignore b/.eslintignore index 17ca04c94..154111996 100644 --- a/.eslintignore +++ b/.eslintignore @@ -4,3 +4,4 @@ node_modules /build /target /.eslintrc.js +/cypress.config.js diff --git a/.eslintrc.js b/.eslintrc.js index 2b5f80b11..5e176b8bb 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -15,9 +15,15 @@ const LICENSE_HEADER = ` */ ` -module.exports = { - root: true, +module.exports = { + root: true, extends: ['@elastic/eslint-config-kibana', 'plugin:@elastic/eui/recommended'], + env: { + 'cypress/globals': true, + }, + plugins: [ + 'cypress', + ], rules: { // "@osd/eslint/require-license-header": "off" '@osd/eslint/no-restricted-paths': [ @@ -27,11 +33,17 @@ module.exports = { zones: [ { target: ['(public|server)/**/*'], - from: ['../../packages/**/*','packages/**/*'] + from: ['../../packages/**/*','packages/**/*'], }, - ] - } - ] + ], + }, + ], + // Add cypress specific rules here + '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', }, overrides: [ { @@ -43,8 +55,8 @@ module.exports = { licenses: [ LICENSE_HEADER ], }, ], - "no-console": 0 - } - } + 'no-console': 0, + }, + }, ], -}; \ No newline at end of file +}; diff --git a/.github/workflows/cypress-test-oidc-e2e.yml b/.github/workflows/cypress-test-oidc-e2e.yml new file mode 100644 index 000000000..c673018b7 --- /dev/null +++ b/.github/workflows/cypress-test-oidc-e2e.yml @@ -0,0 +1,256 @@ +name: Snapshot based E2E OIDC tests workflow +on: + pull_request: + branches: [ '**' ] +env: + OPENSEARCH_VERSION: '3.0.0' + KEYCLOAK_VERSION: '21.0.1' + TEST_KEYCLOAK_CLIENT_SECRET: 'oacHfNaXyy81r2uHq1A9RY4ASryre4rZ' + CI: 1 + # avoid warnings like "tput: No value for $TERM and no -T specified" + TERM: xterm + PLUGIN_NAME: opensearch-security + # This is the SHA256 checksum of the known good kc.sh script for Keycloak version 21.0.1. + KNOWN_CHECKSUM_OF_KEYCLOAK_SCRIPT: 'f825ea1a9ffa5ad91673737c06857ababbb69b6b8f09e0c637b4c998517f9608' + +jobs: + tests: + name: Run Cypress E2E OIDC tests + strategy: + fail-fast: false + matrix: + os: [ ubuntu-latest ] + runs-on: ${{ matrix.os }} + + steps: + - name: Set up JDK + uses: actions/setup-java@v1 + with: + java-version: 11 + + - name: Checkout Branch + uses: actions/checkout@v3 + + - name: Set env + run: | + opensearch_version=$(node -p "require('./package.json').opensearchDashboards.version") + plugin_version=$(node -p "require('./package.json').version") + echo "OPENSEARCH_VERSION=$opensearch_version" >> $GITHUB_ENV + echo "PLUGIN_VERSION=$plugin_version" >> $GITHUB_ENV + shell: bash + + # Download and Check Keycloak Version + - name: Download and Check Keyloak Version on Linux + if: ${{ runner.os == 'Linux' }} + run: | + echo "Downloading Keycloak ${{ env.KEYCLOAK_VERSION }}" + wget https://github.com/keycloak/keycloak/releases/download/${{ env.KEYCLOAK_VERSION }}/keycloak-${{ env.KEYCLOAK_VERSION }}.tar.gz + echo "Unpacking Keycloak" + tar -xzf keycloak-${{ env.KEYCLOAK_VERSION }}.tar.gz + cd keycloak-${{ env.KEYCLOAK_VERSION }}/bin + chmod +x ./kc.sh + echo "Generating checksum for the downloaded kc.sh script..." + DOWNLOADED_CHECKSUM=$(sha256sum kc.sh | awk '{print $1}') + echo "Downloaded kc.sh checksum: $DOWNLOADED_CHECKSUM" + echo "Known good kc.sh checksum: ${{ env.KNOWN_CHECKSUM_OF_KEYCLOAK_SCRIPT }}" + KNOWN_GOOD_CHECKSUM="${{ env.KNOWN_CHECKSUM_OF_KEYCLOAK_SCRIPT }}" + if [ "$DOWNLOADED_CHECKSUM" != "$KNOWN_GOOD_CHECKSUM" ]; then + echo "Checksum mismatch. The kc.sh script does not match the known good version. Please check https://github.com/keycloak/keycloak and verify the updates." + exit 1 + else + echo "Checksum match confirmed. Proceeding with setup." + fi + chmod +x ./kc.sh + + # Setup and Run Keycloak + - name: Get and run Keycloak on Linux + if: ${{ runner.os == 'Linux' }} + run: | + export KEYCLOAK_ADMIN=admin + export KEYCLOAK_ADMIN_PASSWORD=admin + cd keycloak-${{ env.KEYCLOAK_VERSION }}/bin + echo "Starting keycloak" + ./kc.sh start-dev --http-enabled=true --hostname-strict-https=false --http-host=localhost --http-relative-path /auth --health-enabled=true & + timeout 300 bash -c 'while [[ "$(curl -s -o /dev/null -w ''%{http_code}'' localhost:8080/auth/health)" != "200" ]]; do sleep 5; done' + chmod +x kcadm.sh + echo "Creating client" + ./kcadm.sh config credentials --server http://localhost:8080/auth --realm master --user admin --password admin + CID=$(./kcadm.sh create clients -r master -s clientId=opensearch -s secret="${{ env.TEST_KEYCLOAK_CLIENT_SECRET }}" -s 'attributes."access.token.lifespan"=60' -s 'redirectUris=["http://localhost:5603/auth/openid/login", "http://localhost:5601", "http://localhost:5601/auth/openid/login"]' -i) + ./kcadm.sh get clients/$CID/installation/providers/keycloak-oidc-keycloak-json > tmp + echo "Getting client secret for dashboards configuration purpose" + CLIENT_SECRET=$(grep -o '"secret" : "[^"]*' tmp | grep -o '[^"]*$') + echo "KEYCLOAK_CLIENT_SECRET=$CLIENT_SECRET" >> $GITHUB_ENV + echo "The client secret is: $CLIENT_SECRET" + echo "Creating client mapper" + ./kcadm.sh create clients/$CID/protocol-mappers/models -r master -s 'config."id.token.claim"=true' -s 'config."multivalued"=true' -s 'config."claim.name"="roles"' -s 'config."userinfo.token.claim"=true' -s 'config."access.token.claim"=true' -s 'name=rolemapper' -s 'protocolMapper=oidc-usermodel-realm-role-mapper' -s "protocol=openid-connect" + + - name: Download security plugin and create setup scripts + uses: ./.github/actions/download-plugin + with: + opensearch-version: ${{ env.OPENSEARCH_VERSION }} + plugin-name: ${{ env.PLUGIN_NAME }} + plugin-version: ${{ env.PLUGIN_VERSION }} + + # Download OpenSearch + - name: Download OpenSearch for Linux + uses: peternied/download-file@v2 + if: ${{ runner.os == 'Linux' }} + with: + url: https://artifacts.opensearch.org/snapshots/core/opensearch/${{ env.OPENSEARCH_VERSION }}-SNAPSHOT/opensearch-min-${{ env.OPENSEARCH_VERSION }}-SNAPSHOT-linux-x64-latest.tar.gz + + # Extract downloaded tar/zip + - name: Extract downloaded tar + if: ${{ runner.os == 'Linux' }} + run: | + tar -xzf opensearch-*.tar.gz + rm -f opensearch-*.tar.gz + shell: bash + + # Install the security plugin + - name: Install Plugin into OpenSearch for Linux + if: ${{ runner.os == 'Linux'}} + run: | + chmod +x ./opensearch-${{ env.OPENSEARCH_VERSION }}-SNAPSHOT/bin/opensearch-plugin + /bin/bash -c "yes | ./opensearch-${{ env.OPENSEARCH_VERSION }}-SNAPSHOT/bin/opensearch-plugin install file:$(pwd)/opensearch-security.zip" + shell: bash + + # Add OIDC Configuration + - name: Injecting OIDC Configuration for Linux + if: ${{ runner.os == 'Linux'}} + run: | + echo "Creating new SAML configuration" + cd ./opensearch-${{ env.OPENSEARCH_VERSION }}-SNAPSHOT/config/opensearch-security/ + rm -rf config.yml + cat << 'EOT' > config.yml + --- + _meta: + type: "config" + config_version: 2 + config: + dynamic: + http: + anonymous_auth_enabled: false + authc: + basic_internal_auth_domain: + description: "Authenticate via HTTP Basic against internal users database" + http_enabled: true + transport_enabled: true + order: 0 + http_authenticator: + type: basic + challenge: false + authentication_backend: + type: intern + openid_auth_domain: + http_enabled: true + transport_enabled: true + order: 1 + http_authenticator: + type: openid + challenge: false + config: + subject_key: preferred_username + roles_key: roles + openid_connect_url: http://localhost:8080/auth/realms/master/.well-known/openid-configuration + authentication_backend: + type: noop + EOT + echo "THIS IS THE SECURITY CONFIG FILE: " + cat config.yml + + # TODO: REMOVE THIS ONCE ADMIN JAVA TOOL SUPPORT IT + - name: Write password to initialAdminPassword location + if: ${{ runner.os == 'Linux'}} + run: + echo admin >> ./opensearch-${{ env.OPENSEARCH_VERSION }}-SNAPSHOT/config/initialAdminPassword.txt + shell: bash + + # Run any configuration scripts + - name: Run Setup Script for Linux + if: ${{ runner.os == 'Linux' }} + run: | + echo "running linux setup" + chmod +x ./setup.sh + ./setup.sh + shell: bash + + # Run OpenSearch + - name: Run OpenSearch with plugin on Linux + if: ${{ runner.os == 'Linux'}} + run: | + /bin/bash -c "./opensearch-${{ env.OPENSEARCH_VERSION }}-SNAPSHOT/bin/opensearch &" + shell: bash + + # Give the OpenSearch process some time to boot up before sending any requires, might need to increase the default time! + - name: Sleep while OpenSearch starts + uses: peternied/action-sleep@v1 + with: + seconds: 30 + + # Verify that the server is operational + - name: Check OpenSearch Running on Linux + if: ${{ runner.os != 'Windows'}} + run: curl https://localhost:9200/_cat/plugins -u 'admin:admin' -k -v + shell: bash + + - if: always() + run: cat ./opensearch-${{ env.OPENSEARCH_VERSION }}-SNAPSHOT/logs/opensearch.log + shell: bash + + # OSD bootstrap + - name: Run Dashboard with Security Dashboards Plugin + uses: ./.github/actions/install-dashboards + with: + plugin_name: security-dashboards-plugin + + # Configure the Dashboard for OIDC setup + - name: Configure and Run OpenSearch Dashboards with Cypress Test Cases + if: ${{ runner.os == 'Linux' }} + run: | + cd ./OpenSearch-Dashboards + rm -rf ./config/opensearch_dashboards.yml + cat << 'EOT' > ./config/opensearch_dashboards.yml + server.host: "localhost" + opensearch.hosts: ["https://localhost:9200"] + opensearch.ssl.verificationMode: none + opensearch.username: "kibanaserver" + opensearch.password: "kibanaserver" + opensearch.requestHeadersWhitelist: [ authorization,securitytenant ] + opensearch_security.multitenancy.enabled: true + opensearch_security.multitenancy.tenants.preferred: ["Private", "Global"] + opensearch_security.readonly_mode.roles: ["kibana_read_only"] + opensearch_security.cookie.secure: false + opensearch_security.openid.connect_url: "http://127.0.0.1:8080/auth/realms/master/.well-known/openid-configuration" + opensearch_security.openid.client_id: "opensearch" + opensearch_security.openid.client_secret: "${{ env.TEST_KEYCLOAK_CLIENT_SECRET }}" + opensearch_security.auth.type: ["openid"] + opensearch_security.auth.multiple_auth_enabled: true + opensearch_security.ui.openid.login.buttonname: "OIDC" + home.disableWelcomeScreen: true + EOT + echo 'HERE IS THE DASHBOARD CONFIG FILE: ' + cat ./config/opensearch_dashboards.yml + nohup yarn start --no-base-path --no-watch | tee dashboard.log & + + # Check if OSD is ready with a max timeout of 600 seconds + - name : Check If OpenSearch Dashboards Is Ready + if: ${{ runner.os == 'Linux' }} + run: | + cd ./OpenSearch-Dashboards + echo "Start checking OpenSearch Dashboards." + for i in {1..60}; do + if grep -q "bundles compiled successfully after" "dashboard.log"; then + echo "OpenSearch Dashboards compiled successfully." + break + fi + if [ $i -eq 60 ]; then + echo "Timeout for 600 seconds reached. OpenSearch Dashboards did not finish compiling." + exit 1 + fi + sleep 10 + done + + - name: Run Cypress + run : | + yarn add cypress --save-dev + yarn cypress:run --browser chrome --headless --spec 'test/cypress/e2e/oidc/*.js' diff --git a/.github/workflows/cypress-test-saml-e2e.yml b/.github/workflows/cypress-test-saml-e2e.yml new file mode 100644 index 000000000..7a329a9cc --- /dev/null +++ b/.github/workflows/cypress-test-saml-e2e.yml @@ -0,0 +1,216 @@ +name: Snapshot based E2E SAML tests workflow +on: + pull_request: + branches: [ '**' ] +env: + OPENSEARCH_VERSION: '3.0.0' + CI: 1 + # avoid warnings like "tput: No value for $TERM and no -T specified" + TERM: xterm + PLUGIN_NAME: opensearch-security + +jobs: + tests: + name: Run Cypress E2E SAML tests + strategy: + fail-fast: false + matrix: + os: [ ubuntu-latest ] + runs-on: ${{ matrix.os }} + + steps: + - name: Set up JDK + uses: actions/setup-java@v1 + with: + java-version: 11 + + - name: Checkout Branch + uses: actions/checkout@v3 + + - name: Set env + run: | + opensearch_version=$(node -p "require('./package.json').opensearchDashboards.version") + plugin_version=$(node -p "require('./package.json').version") + echo "OPENSEARCH_VERSION=$opensearch_version" >> $GITHUB_ENV + echo "PLUGIN_VERSION=$plugin_version" >> $GITHUB_ENV + shell: bash + + - name: Download security plugin and create setup scripts + uses: ./.github/actions/download-plugin + with: + opensearch-version: ${{ env.OPENSEARCH_VERSION }} + plugin-name: ${{ env.PLUGIN_NAME }} + plugin-version: ${{ env.PLUGIN_VERSION }} + + # Download OpenSearch + - name: Download OpenSearch for Linux + uses: peternied/download-file@v2 + if: ${{ runner.os == 'Linux' }} + with: + url: https://artifacts.opensearch.org/snapshots/core/opensearch/${{ env.OPENSEARCH_VERSION }}-SNAPSHOT/opensearch-min-${{ env.OPENSEARCH_VERSION }}-SNAPSHOT-linux-x64-latest.tar.gz + + # Extract downloaded tar/zip + - name: Extract downloaded tar + if: ${{ runner.os == 'Linux' }} + run: | + tar -xzf opensearch-*.tar.gz + rm -f opensearch-*.tar.gz + shell: bash + + # TODO: REMOVE THIS ONCE ADMIN JAVA TOOL SUPPORT IT + - name: Write password to initialAdminPassword location + if: ${{ runner.os == 'Linux'}} + run: + echo admin >> ./opensearch-${{ env.OPENSEARCH_VERSION }}-SNAPSHOT/config/initialAdminPassword.txt + shell: bash + + # Install the security plugin + - name: Install Plugin into OpenSearch for Linux + if: ${{ runner.os == 'Linux'}} + run: | + chmod +x ./opensearch-${{ env.OPENSEARCH_VERSION }}-SNAPSHOT/bin/opensearch-plugin + /bin/bash -c "yes | ./opensearch-${{ env.OPENSEARCH_VERSION }}-SNAPSHOT/bin/opensearch-plugin install file:$(pwd)/opensearch-security.zip" + shell: bash + + # Add SAML Configuration + - name: Injecting SAML Configuration for Linux + if: ${{ runner.os == 'Linux'}} + run: | + echo "Creating new SAML configuration" + cd ./opensearch-${{ env.OPENSEARCH_VERSION }}-SNAPSHOT/config/opensearch-security/ + rm -rf config.yml + cat << 'EOT' > config.yml + --- + _meta: + type: "config" + config_version: 2 + config: + dynamic: + http: + anonymous_auth_enabled: false + authc: + basic_internal_auth_domain: + description: "Authenticate via HTTP Basic against internal users database" + http_enabled: true + transport_enabled: true + order: 0 + http_authenticator: + type: basic + challenge: false + authentication_backend: + type: intern + saml_auth_domain: + http_enabled: true + transport_enabled: false + order: 1 + http_authenticator: + type: saml + challenge: true + config: + idp: + entity_id: urn:example:idp + metadata_url: http://localhost:7000/metadata + sp: + entity_id: https://localhost:9200 + kibana_url: http://localhost:5601 + exchange_key: 6aff3042-1327-4f3d-82f0-40a157ac4464 + authentication_backend: + type: noop + EOT + echo "THIS IS THE SECURITY CONFIG FILE: " + cat config.yml + + # Run any configuration scripts + - name: Run Setup Script for Linux + if: ${{ runner.os == 'Linux' }} + run: | + echo "running linux setup" + chmod +x ./setup.sh + ./setup.sh + shell: bash + + # Run OpenSearch + - name: Run OpenSearch with plugin on Linux + if: ${{ runner.os == 'Linux'}} + run: | + /bin/bash -c "./opensearch-${{ env.OPENSEARCH_VERSION }}-SNAPSHOT/bin/opensearch &" + shell: bash + + # Give the OpenSearch process some time to boot up before sending any requires, might need to increase the default time! + - name: Sleep while OpenSearch starts + uses: peternied/action-sleep@v1 + with: + seconds: 30 + + # Verify that the server is operational + - name: Check OpenSearch Running on Linux + if: ${{ runner.os != 'Windows'}} + run: curl https://localhost:9200/_cat/plugins -u 'admin:admin' -k -v + shell: bash + + - if: always() + run: cat ./opensearch-${{ env.OPENSEARCH_VERSION }}-SNAPSHOT/logs/opensearch.log + shell: bash + + # OSD bootstrap + - name: Run Dashboard with Security Dashboards Plugin + uses: ./.github/actions/install-dashboards + with: + plugin_name: security-dashboards-plugin + + # Setup and Run SAML Idp + - name: Get and run SAML Idp on Linux + if: ${{ runner.os == 'Linux' }} + run: | + cd ./OpenSearch-Dashboards/plugins/security-dashboards-plugin + yarn pretest:jest_server + + # Configure the Dashboard for SAML setup + - name: Configure and Run OpenSearch Dashboards with SAML Configuration + if: ${{ runner.os == 'Linux' }} + run: | + cd ./OpenSearch-Dashboards + rm -rf ./config/opensearch_dashboards.yml + cat << 'EOT' > ./config/opensearch_dashboards.yml + server.host: "localhost" + opensearch.hosts: ["https://localhost:9200"] + opensearch.ssl.verificationMode: none + opensearch.username: "kibanaserver" + opensearch.password: "kibanaserver" + opensearch.requestHeadersWhitelist: [ authorization,securitytenant ] + opensearch_security.multitenancy.enabled: true + opensearch_security.multitenancy.tenants.preferred: ["Private", "Global"] + opensearch_security.readonly_mode.roles: ["kibana_read_only"] + opensearch_security.cookie.secure: false + server.xsrf.allowlist: ["/_plugins/_security/api/authtoken", "/_opendistro/_security/api/authtoken", "/_opendistro/_security/saml/acs", "/_opendistro/_security/saml/acs/idpinitiated", "/_opendistro/_security/saml/logout"] + opensearch_security.auth.type: ["saml"] + opensearch_security.auth.multiple_auth_enabled: true + opensearch_security.auth.anonymous_auth_enabled: false + home.disableWelcomeScreen: true + EOT + echo 'HERE IS THE DASHBOARD CONFIG FILE: ' + cat ./config/opensearch_dashboards.yml + nohup yarn start --no-base-path --no-watch | tee dashboard.log & + + # Check if OSD is ready with a max timeout of 600 seconds + - name : Check If OpenSearch Dashboards Is Ready + if: ${{ runner.os == 'Linux' }} + run: | + cd ./OpenSearch-Dashboards + echo "Start checking OpenSearch Dashboards." + for i in {1..60}; do + if grep -q "bundles compiled successfully after" "dashboard.log"; then + echo "OpenSearch Dashboards compiled successfully." + break + fi + if [ $i -eq 60 ]; then + echo "Timeout for 600 seconds reached. OpenSearch Dashboards did not finish compiling." + exit 1 + fi + sleep 10 + done + + - name: Run Cypress + run : | + yarn add cypress --save-dev + yarn cypress:run --browser chrome --headless --spec 'test/cypress/e2e/saml/*.js' diff --git a/.gitignore b/.gitignore index 513364a9b..45a42aca7 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,5 @@ yarn-error.log kibana-coverage/ .DS_Store .idea/ +test/cypress/screenshots +test/cypress/downloads diff --git a/cypress.config.js b/cypress.config.js new file mode 100644 index 000000000..56d619ab5 --- /dev/null +++ b/cypress.config.js @@ -0,0 +1,35 @@ +/* + * Copyright OpenSearch Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +const { defineConfig } = require('cypress'); + +module.exports = defineConfig({ + screenshotsFolder: 'test/cypress/screenshots', + downloadsFolder: 'test/cypress/downloads', + defaultCommandTimeout: 60000, + requestTimeout: 60000, + responseTimeout: 60000, + e2e: { + setupNodeEvents(on, config) {}, + supportFile: 'test/cypress/support/e2e.js', + baseUrl: 'http://localhost:5601', + specPattern: 'test/cypress/e2e/**/*.spec.js', + }, + env: { + openSearchUrl: 'https://localhost:9200', + adminUserName: 'admin', + adminPassword: 'admin', + }, +}); diff --git a/package.json b/package.json index e3993e5a5..eea00c4c7 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,8 @@ "license": "Apache-2.0", "homepage": "https://github.com/opensearch-project/security-dashboards-plugin", "scripts": { + "cypress:open": "cypress open", + "cypress:run": "cypress run", "plugin-helpers": "node ../../scripts/plugin_helpers", "osd": "node ../../scripts/osd", "opensearch": "node ../../scripts/opensearch", @@ -25,6 +27,8 @@ "@elastic/eslint-import-resolver-kibana": "link:../../packages/osd-eslint-import-resolver-opensearch-dashboards", "@testing-library/react-hooks": "^7.0.2", "@types/hapi__wreck": "^15.0.1", + "cypress": "^13.5.1", + "cypress-mochawesome-reporter": "^3.3.0", "gulp-rename": "2.0.0", "jose": "^4.11.2", "saml-idp": "^1.2.1", @@ -34,6 +38,7 @@ "dependencies": { "@hapi/cryptiles": "5.0.0", "@hapi/wreck": "^17.1.0", + "eslint-plugin-cypress": "^2.8.1", "html-entities": "1.3.1" }, "resolutions": { diff --git a/test/cypress/e2e/oidc/oidc_auth_test.spec.js b/test/cypress/e2e/oidc/oidc_auth_test.spec.js new file mode 100644 index 000000000..b4c5c80d2 --- /dev/null +++ b/test/cypress/e2e/oidc/oidc_auth_test.spec.js @@ -0,0 +1,125 @@ +/* + * Copyright OpenSearch Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +const login = 'admin'; +const password = 'admin'; + +describe('Log in via OIDC', () => { + afterEach(() => { + cy.origin('http://localhost:5601', () => { + cy.clearCookies(); + cy.clearLocalStorage(); + }); + }); + + const kcLogin = () => { + cy.get('#kc-page-title').should('be.visible'); + cy.get('input[id=username]').should('be.visible').type(login); + cy.get('input[id=password]').should('be.visible').type(password); + cy.get('#kc-login').click(); + }; + + it('Login to app/opensearch_dashboards_overview#/ when OIDC is enabled', () => { + cy.visit('http://localhost:5601/app/opensearch_dashboards_overview', { + failOnStatusCode: false, + }); + + kcLogin(); + + cy.origin('http://localhost:5601', () => { + localStorage.setItem('opendistro::security::tenant::saved', '""'); + localStorage.setItem('home:newThemeModal:show', 'false'); + + cy.get('#osdOverviewPageHeader__title').should('be.visible'); + + cy.getCookie('security_authentication').should('exist'); + }); + }); + + it('Login to app/dev_tools#/console when OIDC is enabled', () => { + cy.visit('http://localhost:5601/app/opensearch_dashboards_overview', { + failOnStatusCode: false, + }); + + kcLogin(); + + cy.origin('http://localhost:5601', () => { + localStorage.setItem('opendistro::security::tenant::saved', '""'); + localStorage.setItem('home:newThemeModal:show', 'false'); + + cy.visit('http://localhost:5601/app/dev_tools#/console'); + + cy.get('a').contains('Dev Tools').should('be.visible'); + + cy.getCookie('security_authentication').should('exist'); + }); + }); + + it('Login to Dashboard with Hash', () => { + cy.visit( + `http://localhost:5601/app/dashboards#/view/7adfa750-4c81-11e8-b3d7-01146121b73d?_g=(filters:!(),refreshInterval:(pause:!f,value:900000),time:(from:now-24h,to:now))&_a=(description:'Analyze%20mock%20flight%20data%20for%20OpenSearch-Air,%20Logstash%20Airways,%20OpenSearch%20Dashboards%20Airlines%20and%20BeatsWest',filters:!(),fullScreenMode:!f,options:(hidePanelTitles:!f,useMargins:!t),query:(language:kuery,query:''),timeRestore:!t,title:'%5BFlights%5D%20Global%20Flight%20Dashboard',viewMode:view)` + ); + + kcLogin(); + + cy.origin('http://localhost:5601', () => { + localStorage.setItem('opendistro::security::tenant::saved', '""'); + localStorage.setItem('home:newThemeModal:show', 'false'); + + cy.get('.euiHeader.euiHeader--default.euiHeader--fixed.primaryHeader').should('be.visible'); + + cy.getCookie('security_authentication').should('exist'); + }); + }); + + it('Tenancy persisted after logout in OIDC', () => { + cy.visit('http://localhost:5601/app/opensearch_dashboards_overview#/', { + failOnStatusCode: false, + }); + + kcLogin(); + + cy.origin('http://localhost:5601', () => { + localStorage.setItem('home:newThemeModal:show', 'false'); + + cy.get('#private').should('be.enabled'); + cy.get('#private').click({ force: true }); + + cy.get('button[data-test-subj="confirm"]').click(); + + cy.get('#osdOverviewPageHeader__title').should('be.visible'); + + cy.get('button[id="user-icon-btn"]').click(); + + cy.get('button[data-test-subj^="log-out-"]').click(); + }); + + kcLogin(); + + cy.origin('http://localhost:5601', () => { + cy.get('#user-icon-btn').should('be.visible'); + cy.get('#user-icon-btn').click(); + + cy.get('#osdOverviewPageHeader__title').should('be.visible'); + + cy.get('#tenantName').should('have.text', 'Private'); + }); + }); +}); diff --git a/test/cypress/e2e/saml/saml_auth_test.spec.js b/test/cypress/e2e/saml/saml_auth_test.spec.js new file mode 100644 index 000000000..925256ee8 --- /dev/null +++ b/test/cypress/e2e/saml/saml_auth_test.spec.js @@ -0,0 +1,121 @@ +/* + * Copyright OpenSearch Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { ALL_ACCESS_ROLE } from '../../support/constants'; + +import samlUserRoleMapping from '../../fixtures/saml/samlUserRoleMappiing.json'; + +before(() => { + cy.intercept('https://localhost:9200'); + + // Avoid Cypress lock onto the ipv4 range, so fake `visit()` before `request()`. + // See: https://github.com/cypress-io/cypress/issues/25397#issuecomment-1402556488 + cy.visit('http://localhost:5601'); + + cy.createRoleMapping(ALL_ACCESS_ROLE, samlUserRoleMapping); + cy.clearCookies(); + cy.clearLocalStorage(); +}); + +afterEach(() => { + cy.clearCookies(); + cy.clearLocalStorage(); +}); + +describe('Log in via SAML', () => { + const samlLogin = () => { + cy.get('input[id=userName]').should('be.visible'); + cy.get('button[id=btn-sign-in]').should('be.visible').click(); + }; + + it('Login to app/opensearch_dashboards_overview#/ when SAML is enabled', () => { + localStorage.setItem('opendistro::security::tenant::saved', '"__user__"'); + localStorage.setItem('home:newThemeModal:show', 'false'); + + cy.visit('http://localhost:5601/app/opensearch_dashboards_overview', { + failOnStatusCode: false, + }); + + samlLogin(); + + cy.get('#osdOverviewPageHeader__title').should('be.visible'); + cy.getCookie('security_authentication').should('exist'); + }); + + it('Login to app/dev_tools#/console when SAML is enabled', () => { + localStorage.setItem('opendistro::security::tenant::saved', '"__user__"'); + localStorage.setItem('home:newThemeModal:show', 'false'); + + cy.visit('http://localhost:5601/app/dev_tools#/console', { + failOnStatusCode: false, + }); + + samlLogin(); + + cy.get('a.euiBreadcrumb--last').contains('Dev Tools'); + cy.getCookie('security_authentication').should('exist'); + }); + + it('Login to Dashboard with Hash', () => { + localStorage.setItem('opendistro::security::tenant::saved', '"__user__"'); + localStorage.setItem('home:newThemeModal:show', 'false'); + + const urlWithHash = `http://localhost:5601/app/security-dashboards-plugin#/getstarted`; + + cy.visit(urlWithHash, { + failOnStatusCode: false, + }); + + samlLogin(); + + cy.get('h1.euiTitle--large').contains('Get started'); + cy.getCookie('security_authentication').should('exist'); + }); + + it('Tenancy persisted after logout in SAML', () => { + localStorage.setItem('home:newThemeModal:show', 'false'); + + cy.visit('http://localhost:5601/app/opensearch_dashboards_overview', { + failOnStatusCode: false, + }); + + samlLogin(); + + cy.get('#private').should('be.enabled'); + cy.get('#private').click({ force: true }); + + cy.get('button[data-test-subj="confirm"]').click(); + + cy.get('#osdOverviewPageHeader__title').should('be.visible'); + + cy.get('button[id="user-icon-btn"]').click(); + + cy.get('button[data-test-subj^="log-out-"]').click(); + + samlLogin(); + + cy.get('#user-icon-btn').should('be.visible'); + cy.get('#user-icon-btn').click(); + + cy.get('#osdOverviewPageHeader__title').should('be.visible'); + + cy.get('#tenantName').should('have.text', 'Private'); + }); +}); diff --git a/test/cypress/fixtures/saml/samlUserRoleMappiing.json b/test/cypress/fixtures/saml/samlUserRoleMappiing.json new file mode 100644 index 000000000..b1f015cfc --- /dev/null +++ b/test/cypress/fixtures/saml/samlUserRoleMappiing.json @@ -0,0 +1,4 @@ +{ + "backend_roles" : [ "admin" ], + "users" : [ "saml.jackson@example.com" ] +} diff --git a/test/cypress/support/commands.js b/test/cypress/support/commands.js new file mode 100644 index 000000000..ade3591cf --- /dev/null +++ b/test/cypress/support/commands.js @@ -0,0 +1,80 @@ +/* + * Copyright OpenSearch Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { SEC_API, ADMIN_AUTH } from './constants'; + +/** + * Overwrite request command to support authentication similar to visit. + * The request function parameters can be url, or (method, url), or (method, url, body). + */ +Cypress.Commands.overwrite('request', (originalFn, ...args) => { + const defaults = {}; + defaults.auth = ADMIN_AUTH; + let options = {}; + if (typeof args[0] === 'object' && args[0] !== null) { + options = { ...args[0] }; + } else if (args.length === 1) { + [options.url] = args; + } else if (args.length === 2) { + [options.method, options.url] = args; + } else if (args.length === 3) { + [options.method, options.url, options.body] = args; + } + + return originalFn({ ...defaults, ...options }); +}); + +Cypress.Commands.add('createTenant', (tenantID, tenantJson) => { + cy.request( + 'PUT', + `${Cypress.env('openSearchUrl')}${SEC_API.TENANTS_BASE}/${tenantID}`, + tenantJson + ).then((response) => { + expect(response.status).to.eq(200); + }); +}); + +Cypress.Commands.add('createInternalUser', (userID, userJson) => { + cy.request( + 'PUT', + `${Cypress.env('openSearchUrl')}${SEC_API.INTERNALUSERS_BASE}/${userID}`, + userJson + ).then((response) => { + expect(response.status).to.eq(200); + }); +}); + +Cypress.Commands.add('createRole', (roleID, roleJson) => { + cy.request('PUT', `${Cypress.env('openSearchUrl')}${SEC_API.ROLE_BASE}/${roleID}`, roleJson).then( + (response) => { + expect(response.status).to.eq(200); + } + ); +}); + +Cypress.Commands.add('createRoleMapping', (roleID, rolemappingJson) => { + cy.request( + 'PUT', + `${Cypress.env('openSearchUrl')}${SEC_API.ROLE_MAPPING_BASE}/${roleID}`, + rolemappingJson + ).then((response) => { + expect(response.status).to.eq(200); + }); +}); diff --git a/test/cypress/support/constants.js b/test/cypress/support/constants.js new file mode 100644 index 000000000..95cb4da04 --- /dev/null +++ b/test/cypress/support/constants.js @@ -0,0 +1,42 @@ +/* + * Copyright OpenSearch Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + ***************************** + SECURITY DASHBOARDS PLUGIN CONSTANTS + ***************************** + */ + +export const ALL_ACCESS_ROLE = 'all_access'; + +//Admin Credential +export const ADMIN_AUTH = { + username: Cypress.env('adminUserName'), + password: Cypress.env('adminPassword'), +}; + +//Security API Constants +export const SEC_API_PREFIX = '/_plugins/_security/api'; +export const SEC_API = { + TENANTS_BASE: `${SEC_API_PREFIX}/tenants`, + INTERNALUSERS_BASE: `${SEC_API_PREFIX}/internalusers`, + ROLE_BASE: `${SEC_API_PREFIX}/roles`, + ROLE_MAPPING_BASE: `${SEC_API_PREFIX}/rolesmapping`, +}; diff --git a/test/cypress/support/e2e.js b/test/cypress/support/e2e.js new file mode 100644 index 000000000..433a1cab9 --- /dev/null +++ b/test/cypress/support/e2e.js @@ -0,0 +1,36 @@ +/* + * Copyright OpenSearch Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +// *********************************************************** +// This example support/e2e.js 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'; diff --git a/test/cypress/support/index.d.ts b/test/cypress/support/index.d.ts new file mode 100644 index 000000000..61362a8c4 --- /dev/null +++ b/test/cypress/support/index.d.ts @@ -0,0 +1,55 @@ +/* + * Copyright OpenSearch Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +// type definitions for custom commands like "createDefaultTodos" +// / + +declare namespace Cypress { + interface Chainable { + /** + * Create a test tenant by calling REST API + * @example + * cy.createTenant('test_tenant', tenantJsonFixture ) + */ + createTenant(tenantID: string, tenantJson: string): Chainable; + } + + interface Chainable { + /** + * Create an internal user by calling REST API + * @example + * cy.createInternalUser('test_user', userJsonFixture ) + */ + createInternalUser(userID: string, userJson: string): Chainable; + } + + interface Chainable { + /** + * Create a role by calling REST API + * @example + * cy.createRole('role_name', roleJsonFixture ) + */ + createRole(roleID: string, roleJson: string): Chainable; + } + + interface Chainable { + /** + * Create a role mapping by calling REST API + * @example + * cy.createRoleMapping('role_name', rolemappingJsonFixture ) + */ + createRoleMapping(roleID: string, rolemappingJson: string): Chainable; + } +} diff --git a/test/jest_integration/saml_auth.test.ts b/test/jest_integration/saml_auth.test.ts deleted file mode 100644 index e48635e41..000000000 --- a/test/jest_integration/saml_auth.test.ts +++ /dev/null @@ -1,374 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -import * as osdTestServer from '../../../../src/core/test_helpers/osd_server'; -import { Root } from '../../../../src/core/server/root'; -import { resolve } from 'path'; -import { describe, expect, it, beforeAll, afterAll } from '@jest/globals'; -import { - ADMIN_CREDENTIALS, - OPENSEARCH_DASHBOARDS_SERVER_USER, - OPENSEARCH_DASHBOARDS_SERVER_PASSWORD, -} from '../constant'; -import wreck from '@hapi/wreck'; -import { Builder, By, until } from 'selenium-webdriver'; -import { Options } from 'selenium-webdriver/firefox'; -import { AuthType } from '../../common'; - -describe('start OpenSearch Dashboards server', () => { - let root: Root; - let config; - - // XPath Constants - const userIconBtnXPath = '//button[@id="user-icon-btn"]'; - const signInBtnXPath = '//*[@id="btn-sign-in"]'; - const skipWelcomeBtnXPath = '//button[@data-test-subj="skipWelcomeScreen"]'; - const tenantNameLabelXPath = '//*[@id="tenantName"]'; - const pageTitleXPath = '//*[@id="osdOverviewPageHeader__title"]'; - const tenantSwitchBtnXPath = '//button[@data-test-subj="switch-tenants"]'; - // Browser Settings - const browser = 'firefox'; - const options = new Options().headless(); - - beforeAll(async () => { - root = osdTestServer.createRootWithSettings( - { - plugins: { - scanDirs: [resolve(__dirname, '../..')], - }, - home: { disableWelcomeScreen: true }, - server: { - host: 'localhost', - port: 5601, - xsrf: { - whitelist: [ - '/_opendistro/_security/saml/acs/idpinitiated', - '/_opendistro/_security/saml/acs', - '/_opendistro/_security/saml/logout', - ], - }, - }, - logging: { - silent: true, - verbose: false, - }, - opensearch: { - hosts: ['https://localhost:9200'], - ignoreVersionMismatch: true, - ssl: { verificationMode: 'none' }, - username: OPENSEARCH_DASHBOARDS_SERVER_USER, - password: OPENSEARCH_DASHBOARDS_SERVER_PASSWORD, - requestHeadersWhitelist: ['authorization', 'securitytenant'], - }, - opensearch_security: { - auth: { - anonymous_auth_enabled: false, - type: AuthType.SAML, - }, - multitenancy: { - enabled: true, - tenants: { - enable_global: true, - enable_private: true, - preferred: ['Private', 'Global'], - }, - }, - }, - }, - { - // to make ignoreVersionMismatch setting work - // can be removed when we have corresponding ES version - dev: true, - } - ); - - console.log('Starting OpenSearchDashboards server..'); - await root.setup(); - await root.start(); - - await wreck.patch('https://localhost:9200/_plugins/_security/api/rolesmapping/all_access', { - payload: [ - { - op: 'add', - path: '/users', - value: ['saml.jackson@example.com'], - }, - ], - rejectUnauthorized: false, - headers: { - 'Content-Type': 'application/json', - authorization: ADMIN_CREDENTIALS, - }, - }); - console.log('Starting to Download Flights Sample Data'); - await wreck.post('http://localhost:5601/api/sample_data/flights', { - payload: {}, - rejectUnauthorized: false, - headers: { - 'Content-Type': 'application/json', - authorization: ADMIN_CREDENTIALS, - security_tenant: 'global', - }, - }); - console.log('Downloaded Sample Data'); - const getConfigResponse = await wreck.get( - 'https://localhost:9200/_plugins/_security/api/securityconfig', - { - rejectUnauthorized: false, - headers: { - authorization: ADMIN_CREDENTIALS, - }, - } - ); - const responseBody = (getConfigResponse.payload as Buffer).toString(); - config = JSON.parse(responseBody).config; - const samlConfig = { - http_enabled: true, - transport_enabled: false, - order: 5, - http_authenticator: { - challenge: true, - type: AuthType.SAML, - config: { - idp: { - metadata_url: 'http://localhost:7000/metadata', - entity_id: 'urn:example:idp', - }, - sp: { - entity_id: 'https://localhost:9200', - }, - kibana_url: 'http://localhost:5601', - exchange_key: '6aff3042-1327-4f3d-82f0-40a157ac4464', - }, - }, - authentication_backend: { - type: 'noop', - config: {}, - }, - }; - try { - config.dynamic!.authc!.saml_auth_domain = samlConfig; - config.dynamic!.authc!.basic_internal_auth_domain.http_authenticator.challenge = false; - config.dynamic!.http!.anonymous_auth_enabled = false; - await wreck.put('https://localhost:9200/_plugins/_security/api/securityconfig/config', { - payload: config, - rejectUnauthorized: false, - headers: { - 'Content-Type': 'application/json', - authorization: ADMIN_CREDENTIALS, - }, - }); - } catch (error) { - console.log('Got an error while updating security config!!', error.stack); - fail(error); - } - }); - - afterAll(async () => { - console.log('Remove the Sample Data'); - await wreck - .delete('http://localhost:5601/api/sample_data/flights', { - rejectUnauthorized: false, - headers: { - 'Content-Type': 'application/json', - authorization: ADMIN_CREDENTIALS, - }, - }) - .then((value) => { - Promise.resolve(value); - }) - .catch((value) => { - Promise.resolve(value); - }); - console.log('Remove the Role Mapping'); - await wreck - .patch('https://localhost:9200/_plugins/_security/api/rolesmapping/all_access', { - payload: [ - { - op: 'remove', - path: '/users', - users: ['saml.jackson@example.com'], - }, - ], - rejectUnauthorized: false, - headers: { - 'Content-Type': 'application/json', - authorization: ADMIN_CREDENTIALS, - }, - }) - .then((value) => { - Promise.resolve(value); - }) - .catch((value) => { - Promise.resolve(value); - }); - console.log('Remove the Security Config'); - await wreck - .patch('https://localhost:9200/_plugins/_security/api/securityconfig', { - payload: [ - { - op: 'remove', - path: '/config/dynamic/authc/saml_auth_domain', - }, - ], - rejectUnauthorized: false, - headers: { - 'Content-Type': 'application/json', - authorization: ADMIN_CREDENTIALS, - }, - }) - .then((value) => { - Promise.resolve(value); - }) - .catch((value) => { - Promise.resolve(value); - }); - // shutdown OpenSearchDashboards server - await root.shutdown(); - }); - - it('Login to app/opensearch_dashboards_overview#/ when SAML is enabled', async () => { - const driver = getDriver(browser, options).build(); - await driver.get('http://localhost:5601/app/opensearch_dashboards_overview#/'); - await driver.findElement(By.id('btn-sign-in')).click(); - await driver.wait(until.elementsLocated(By.xpath(pageTitleXPath)), 10000); - - const cookie = await driver.manage().getCookies(); - expect(cookie.length).toEqual(3); - await driver.manage().deleteAllCookies(); - await driver.quit(); - }); - - it('Login to app/dev_tools#/console when SAML is enabled', async () => { - const driver = getDriver(browser, options).build(); - await driver.get('http://localhost:5601/app/dev_tools#/console'); - await driver.findElement(By.id('btn-sign-in')).click(); - - await driver.wait( - until.elementsLocated(By.xpath('//*[@data-test-subj="sendRequestButton"]')), - 10000 - ); - - const cookie = await driver.manage().getCookies(); - expect(cookie.length).toEqual(3); - await driver.manage().deleteAllCookies(); - await driver.quit(); - }); - - it('Login to Dashboard with Hash', async () => { - const urlWithHash = `http://localhost:5601/app/security-dashboards-plugin#/getstarted`; - const driver = getDriver(browser, options).build(); - await driver.manage().deleteAllCookies(); - await driver.get(urlWithHash); - await driver.findElement(By.xpath(signInBtnXPath)).click(); - // TODO Use a better XPath. - await driver.wait( - until.elementsLocated(By.xpath('/html/body/div[1]/div/header/div/div[2]')), - 20000 - ); - const windowHash = await driver.getCurrentUrl(); - expect(windowHash).toEqual(urlWithHash); - const cookie = await driver.manage().getCookies(); - expect(cookie.length).toEqual(3); - await driver.manage().deleteAllCookies(); - await driver.quit(); - }); - - it.skip('Tenancy persisted after Logout in SAML', async () => { - const driver = getDriver(browser, options).build(); - - await driver.get('http://localhost:5601/app/opensearch_dashboards_overview#/'); - - await driver.findElement(By.xpath(signInBtnXPath)).click(); - - await driver.wait(until.elementsLocated(By.xpath(pageTitleXPath)), 10000); - - await driver.wait( - until.elementsLocated(By.xpath('//button[@aria-label="Closes this modal window"]')), - 10000 - ); - - // Select Global Tenant Radio Button - const radio = await driver.findElement(By.xpath('//input[@id="global"]')); - await driver.executeScript('arguments[0].scrollIntoView(true);', radio); - await driver.executeScript('arguments[0].click();', radio); - - await driver.wait(until.elementIsSelected(radio)); - - await driver.findElement(By.xpath('//button[@data-test-subj="confirm"]')).click(); - - await driver.wait(until.elementsLocated(By.xpath(userIconBtnXPath)), 10000); - - await driver.findElement(By.xpath(userIconBtnXPath)).click(); - - await driver.findElement(By.xpath('//*[@data-test-subj="log-out-1"]')).click(); - - // RELOGIN AND CHECK TENANT - - await driver.wait(until.elementsLocated(By.xpath(signInBtnXPath)), 10000); - - await driver.findElement(By.xpath(signInBtnXPath)).click(); - - await driver.wait(until.elementsLocated(By.xpath(skipWelcomeBtnXPath)), 10000); - - await driver.findElement(By.xpath(skipWelcomeBtnXPath)).click(); - - await driver.findElement(By.xpath(userIconBtnXPath)).click(); - - await driver.wait(until.elementsLocated(By.xpath(tenantNameLabelXPath)), 10000); - - const tenantName = await driver.findElement(By.xpath(tenantNameLabelXPath)).getText(); - const localStorageItem = await driver.executeScript( - `return window.localStorage.getItem("opendistro::security::tenant::saved")` - ); - - // Retry previous steps one more time if the webdriver doens't reload as expected - if (tenantName === 'Private' && localStorageItem === '""') { - await driver.wait(until.elementsLocated(By.xpath(tenantSwitchBtnXPath)), 10000); - await driver.findElement(By.xpath(tenantSwitchBtnXPath)).click(); - - await driver.executeScript('arguments[0].scrollIntoView(true);', radio); - await driver.executeScript('arguments[0].click();', radio); - await driver.wait(until.elementIsSelected(radio)); - - await driver.findElement(By.xpath('//button[@data-test-subj="confirm"]')).click(); - - await driver.wait(until.elementsLocated(By.xpath(userIconBtnXPath)), 10000); - await driver.findElement(By.xpath(userIconBtnXPath)).click(); - await driver.findElement(By.xpath('//*[@data-test-subj="log-out-1"]')).click(); - - await driver.wait(until.elementsLocated(By.xpath(signInBtnXPath)), 10000); - await driver.findElement(By.xpath(signInBtnXPath)).click(); - - await driver.wait(until.elementsLocated(By.xpath(userIconBtnXPath)), 10000); - await driver.findElement(By.xpath(userIconBtnXPath)).click(); - await driver.wait(until.elementsLocated(By.xpath(tenantNameLabelXPath)), 10000); - - const newtenantName = await driver.findElement(By.xpath(tenantNameLabelXPath)).getText(); - expect(newtenantName).toEqual('Global'); - } else { - expect(localStorageItem).toEqual('""'); - expect(tenantName).toEqual('Global'); - } - await driver.manage().deleteAllCookies(); - await driver.quit(); - - expect(localStorageItem).toEqual('""'); - }); -}); - -function getDriver(browser: string, options: Options) { - return new Builder().forBrowser(browser).setFirefoxOptions(options); -} From ec661f8847e090c3293bb018c08b51625232cbf5 Mon Sep 17 00:00:00 2001 From: Simple-Analysis <74850112+Simple-Analysis@users.noreply.github.com> Date: Thu, 30 Nov 2023 15:08:55 -0700 Subject: [PATCH 18/32] Added client certificate options to support mutual TLS for OpenID endpoint (#1650) * Added client certificate options to support mutual TLS --------- Signed-off-by: Calvin Harrison <74850112+Simple-Analysis@users.noreply.github.com> Signed-off-by: Simple-Analysis <74850112+Simple-Analysis@users.noreply.github.com> Co-authored-by: Peter Nied --- server/auth/types/openid/openid_auth.test.ts | 94 ++++++++++++++++++- server/auth/types/openid/openid_auth.ts | 41 +++++++- server/index.ts | 4 + server/utils/object_properties_defined.ts | 24 +++++ test/certs/cert.pem | 35 +++++++ test/certs/keyStore.p12 | Bin 0 -> 4333 bytes test/certs/private-key.pem | 52 ++++++++++ 7 files changed, 243 insertions(+), 7 deletions(-) create mode 100644 server/utils/object_properties_defined.ts create mode 100644 test/certs/cert.pem create mode 100644 test/certs/keyStore.p12 create mode 100644 test/certs/private-key.pem diff --git a/server/auth/types/openid/openid_auth.test.ts b/server/auth/types/openid/openid_auth.test.ts index f998d844f..55f730481 100644 --- a/server/auth/types/openid/openid_auth.test.ts +++ b/server/auth/types/openid/openid_auth.test.ts @@ -21,20 +21,27 @@ import { OpenIdAuthentication } from './openid_auth'; import { SecurityPluginConfigType } from '../../../index'; import { SecuritySessionCookie } from '../../../session/security_cookie'; import { deflateValue } from '../../../utils/compression'; +import { getObjectProperties } from '../../../utils/object_properties_defined'; import { IRouter, CoreSetup, ILegacyClusterClient, - Logger, SessionStorageFactory, } from '../../../../../../src/core/server'; +interface Logger { + debug(message: string): void; + info(message: string): void; + warn(message: string): void; + error(message: string): void; + fatal(message: string): void; +} + describe('test OpenId authHeaderValue', () => { let router: IRouter; let core: CoreSetup; let esClient: ILegacyClusterClient; let sessionStorageFactory: SessionStorageFactory; - let logger: Logger; // Consistent with auth_handler_factory.test.ts beforeEach(() => {}); @@ -50,6 +57,14 @@ describe('test OpenId authHeaderValue', () => { }, } as unknown) as SecurityPluginConfigType; + const logger = { + debug: (message: string) => {}, + info: (message: string) => {}, + warn: (message: string) => {}, + error: (message: string) => {}, + fatal: (message: string) => {}, + }; + test('make sure that cookies with authHeaderValue are still valid', async () => { const openIdAuthentication = new OpenIdAuthentication( config, @@ -117,4 +132,79 @@ describe('test OpenId authHeaderValue', () => { expect(headers).toEqual(expectedHeaders); }); + + test('Make sure that wreckClient can be configured with mTLS', async () => { + const customConfig = { + openid: { + certificate: 'test/certs/cert.pem', + private_key: 'test/certs/private-key.pem', + header: 'authorization', + scope: [], + }, + }; + + const openidConfig = (customConfig as unknown) as SecurityPluginConfigType; + + const openIdAuthentication = new OpenIdAuthentication( + openidConfig, + sessionStorageFactory, + router, + esClient, + core, + logger + ); + + const wreckHttpsOptions = openIdAuthentication.getWreckHttpsOptions(); + + console.log( + '============= PEM =============', + '\n\n', + getObjectProperties(customConfig.openid, 'OpenID'), + '\n\n', + getObjectProperties(wreckHttpsOptions, 'wreckHttpsOptions') + ); + + expect(wreckHttpsOptions.key).toBeDefined(); + expect(wreckHttpsOptions.cert).toBeDefined(); + expect(wreckHttpsOptions.pfx).toBeUndefined(); + }); + + test('Ensure private key and certificate are not exposed when using PFX certificate', async () => { + const customConfig = { + openid: { + pfx: 'test/certs/keyStore.p12', + certificate: 'test/certs/cert.pem', + private_key: 'test/certs/private-key.pem', + passphrase: '', + header: 'authorization', + scope: [], + }, + }; + + const openidConfig = (customConfig as unknown) as SecurityPluginConfigType; + + const openIdAuthentication = new OpenIdAuthentication( + openidConfig, + sessionStorageFactory, + router, + esClient, + core, + logger + ); + + const wreckHttpsOptions = openIdAuthentication.getWreckHttpsOptions(); + + console.log( + '============= PFX =============', + '\n\n', + getObjectProperties(customConfig.openid, 'OpenID'), + '\n\n', + getObjectProperties(wreckHttpsOptions, 'wreckHttpsOptions') + ); + + expect(wreckHttpsOptions.pfx).toBeDefined(); + expect(wreckHttpsOptions.key).toBeUndefined(); + expect(wreckHttpsOptions.cert).toBeUndefined(); + expect(wreckHttpsOptions.passphrase).toBeUndefined(); + }); }); diff --git a/server/auth/types/openid/openid_auth.ts b/server/auth/types/openid/openid_auth.ts index accabb7c1..747cb84eb 100644 --- a/server/auth/types/openid/openid_auth.ts +++ b/server/auth/types/openid/openid_auth.ts @@ -36,6 +36,7 @@ import { OpenIdAuthRoutes } from './routes'; import { AuthenticationType } from '../authentication_type'; import { callTokenEndpoint } from './helper'; import { composeNextUrlQueryParam } from '../../../utils/next_url'; +import { getObjectProperties } from '../../../utils/object_properties_defined'; import { getExpirationDate } from './helper'; import { AuthType, OPENID_AUTH_LOGIN } from '../../../../common'; import { @@ -55,6 +56,10 @@ export interface OpenIdAuthConfig { export interface WreckHttpsOptions { ca?: string | Buffer | Array; + cert?: string | Buffer | Array; + key?: string | Buffer | Array; + passphrase?: string; + pfx?: string | Buffer | Array; checkServerIdentity?: (host: string, cert: PeerCertificate) => Error | undefined; } @@ -65,6 +70,7 @@ export class OpenIdAuthentication extends AuthenticationType { private authHeaderName: string; private openIdConnectUrl: string; private wreckClient: typeof wreck; + private wreckHttpsOption: WreckHttpsOptions = {}; constructor( config: SecurityPluginConfigType, @@ -119,21 +125,42 @@ export class OpenIdAuthentication extends AuthenticationType { } private createWreckClient(): typeof wreck { - const wreckHttpsOption: WreckHttpsOptions = {}; if (this.config.openid?.root_ca) { - wreckHttpsOption.ca = [fs.readFileSync(this.config.openid.root_ca)]; + this.wreckHttpsOption.ca = [fs.readFileSync(this.config.openid.root_ca)]; + this.logger.debug(`Using CA Cert: ${this.config.openid.root_ca}`); + } + if (this.config.openid?.pfx) { + // Use PFX or PKCS12 if provided + this.logger.debug(`Using PFX or PKCS12: ${this.config.openid.pfx}`); + this.wreckHttpsOption.pfx = [fs.readFileSync(this.config.openid.pfx)]; + } else if (this.config.openid?.certificate && this.config.openid?.private_key) { + // Use 'certificate' and 'private_key' if provided + this.logger.debug(`Using Certificate: ${this.config.openid.certificate}`); + this.logger.debug(`Using Private Key: ${this.config.openid.private_key}`); + this.wreckHttpsOption.cert = [fs.readFileSync(this.config.openid.certificate)]; + this.wreckHttpsOption.key = [fs.readFileSync(this.config.openid.private_key)]; + } else { + this.logger.debug( + `Client certificates not provided. Mutual TLS will not be used to obtain endpoints.` + ); + } + // Check if passphrase is provided, use it for 'pfx' and 'key' + if (this.config.openid?.passphrase !== '') { + this.logger.debug(`Passphrase not provided for private key and/or pfx.`); + this.wreckHttpsOption.passphrase = this.config.openid?.passphrase; } if (this.config.openid?.verify_hostnames === false) { this.logger.debug(`openId auth 'verify_hostnames' option is off.`); - wreckHttpsOption.checkServerIdentity = (host: string, cert: PeerCertificate) => { + this.wreckHttpsOption.checkServerIdentity = (host: string, cert: PeerCertificate) => { return undefined; }; } - if (Object.keys(wreckHttpsOption).length > 0) { + this.logger.info(getObjectProperties(this.wreckHttpsOption, 'WreckHttpsOptions')); + if (Object.keys(this.wreckHttpsOption).length > 0) { return wreck.defaults({ agents: { http: new HTTP.Agent(), - https: new HTTPS.Agent(wreckHttpsOption), + https: new HTTPS.Agent(this.wreckHttpsOption), httpsAllowUnauthorized: new HTTPS.Agent({ rejectUnauthorized: false, }), @@ -144,6 +171,10 @@ export class OpenIdAuthentication extends AuthenticationType { } } + getWreckHttpsOptions(): WreckHttpsOptions { + return this.wreckHttpsOption; + } + createExtraStorage() { // @ts-ignore const hapiServer: Server = this.sessionStorageFactory.asScoped({}).server; diff --git a/server/index.ts b/server/index.ts index c1af7fa16..915da0315 100644 --- a/server/index.ts +++ b/server/index.ts @@ -178,6 +178,10 @@ export const configSchema = schema.object({ base_redirect_url: schema.string({ defaultValue: '' }), logout_url: schema.string({ defaultValue: '' }), root_ca: schema.string({ defaultValue: '' }), + certificate: schema.string({ defaultValue: '' }), + private_key: schema.string({ defaultValue: '' }), + passphrase: schema.string({ defaultValue: '' }), + pfx: schema.string({ defaultValue: '' }), verify_hostnames: schema.boolean({ defaultValue: true }), refresh_tokens: schema.boolean({ defaultValue: true }), trust_dynamic_headers: schema.boolean({ defaultValue: false }), diff --git a/server/utils/object_properties_defined.ts b/server/utils/object_properties_defined.ts new file mode 100644 index 000000000..fc1337146 --- /dev/null +++ b/server/utils/object_properties_defined.ts @@ -0,0 +1,24 @@ +/* + * Copyright OpenSearch Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +export function getObjectProperties(obj: Record, objName: string): string { + const objSummary: string[] = []; + + for (const [key, value] of Object.entries(obj)) { + objSummary.push(`${key}: ${value !== undefined ? 'Defined' : 'Not Defined'}`); + } + + return `${objName} properties:\n${objSummary.map((option) => ` ${option}`).join('\n')}`; +} diff --git a/test/certs/cert.pem b/test/certs/cert.pem new file mode 100644 index 000000000..33f8b236d --- /dev/null +++ b/test/certs/cert.pem @@ -0,0 +1,35 @@ +-----BEGIN CERTIFICATE----- +MIIGJzCCBA+gAwIBAgIUMlm6Xg1wnOLi9gRLy3v4jF5U2JcwDQYJKoZIhvcNAQEL +BQAwgaIxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQK +DBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxFjAUBgNVBAMMDVRlc3RlciBNY1Vu +aXQxQzBBBgkqhkiG9w0BCQEWNHRlc3Rlci5tY3VuaXRAb3BlbnNlYXJjaGRhc2hi +b2FyZHNzZWN1cml0eXBsdWdpbi5jb20wHhcNMjMxMTIzMDg1NzQwWhcNMjQxMTIy +MDg1NzQwWjCBojELMAkGA1UEBhMCVVMxEzARBgNVBAgMClNvbWUtU3RhdGUxITAf +BgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEWMBQGA1UEAwwNVGVzdGVy +IE1jVW5pdDFDMEEGCSqGSIb3DQEJARY0dGVzdGVyLm1jdW5pdEBvcGVuc2VhcmNo +ZGFzaGJvYXJkc3NlY3VyaXR5cGx1Z2luLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQAD +ggIPADCCAgoCggIBALLtHnXJyc7t50o2AlhzpaoZP81l80BYfEGf8wolNrlMXzJ7 +M32X7hG5quSdqlurUSS1L9hkl7Taqbq4fsiGrZX/s+8nkYDRfnaCU6nFH5gvwKcC +bPJyVCYKhuYL0qqKWjek+orknr3P6a7J6Db+eg6HuXlPFLl//JNwYrTBYtaymtaq +ek4mNyxUXlFq/4DXWDCe6DjMhdxdA56vB/3yF4qIdbKjhXuyIsNvMOLEsJe7c7tA ++7E1595vOX+jERSASDn7qA310tc9/NImobHz1fFBD3wL/WWMjfbRPLPC1LSM18EY +o3Cn9mDvHxXy/GHYq9AN5P7esQ0WmIA3AAZR0mUIDOGTG2kFIGlo9sSRBJ+Ygbf7 +7cCA9WE8cqAsEgajT9ZQRxYtGFJyK/M8mSldS+k0TMyWWR0wUeEdknGaTnfYx8lX +LcUFjWM6lTdJam4lereX7qkoJlxCadHPDpW+DIE55dOR9PVvVJtAOeMVZtMe7veo +QW4AMZFjV87rQKdzmQYEu1hLWyDOl46QA9U8nZhYc9A5TGGMDUwhvscoNQ7DjUt/ +O29IL/n9wpaa3hA/K3adg6hmSL57HBR4OxPRfNLT4c77zEyTTqpK9v0m5UGcKJyF +m7gQpG9MAdCjCA1JfzWXLLkA/Wsz7OVppYmhH7+dawwLKBAHC1bUo2iWx38TAgMB +AAGjUzBRMB0GA1UdDgQWBBQIkBuvFnIXXVsQ4xsWy5/OIoV0uDAfBgNVHSMEGDAW +gBQIkBuvFnIXXVsQ4xsWy5/OIoV0uDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3 +DQEBCwUAA4ICAQBRgxLAsPfEiG2rYplRCw/NMfI10EyiiWl0711LiIw3C47eQiC/ +sK7YXWsl4UTRtMyuK7kPTJf3g9e8VDHGyUZfqtBK2+ZYZSV49DWjb2ihWyK7TT1p +bvIW64gSWVWi6J5WOjBbHnlqaggjfNxo76VRaWP2e14m0B5QsnNYvG9LqK++27IL +ESZhb+Vd3NmVlcWIae1CXT8rdsAI3MR30aNDLnK2/YStfvDdgPGKC9VDqoBSywos +FPTVL+eqGAie9xDcSPpCpqCqGzPQk/Si25b9rUUWfxNyMomyVYeHTaZbT6XralKH +6ZtZwi8nuKw9/TKnMH2fAoBk9ZEq47ididzrPTZKDk5MDicpwWwX2JJbilcqWOGQ +0qeJsZk4zCNzLRiX8jjd0kLCfV0KcqRp2Skr0bAlO/KU8cvP2+IV92PnsB5ZD+yi +BmurX0tUT8DAusq3JLzJiBrngWpfUR0uQRzzJqHK8vtVOq+4BnxC6YEgnL5MIKCL +FDdQnE9G/t4N+Bot631Zfhm4KDSB9ycodAsdMujBco6GJdWbSueZB8YdGcBx47ig +1u1yDRqETXRyCU2PITxHbtBlgCkeNPRxlulz18WJLTlAPBhiZrS8GTqo7FjlE78N +GhgJ37+mzqK68J/PRVXpF3jLl0jhSEyUtgLTH/+y33WERhF6BG5cnYOlNA== +-----END CERTIFICATE----- diff --git a/test/certs/keyStore.p12 b/test/certs/keyStore.p12 new file mode 100644 index 0000000000000000000000000000000000000000..ca99176c6b06422af2233c5aa36f1e4dcae449af GIT binary patch literal 4333 zcmVB>X`0s;sCfPw~yk1eLd4bx(z-TKh#1Ct;SAB3QmgNo2k(Wz}GocO}!h(1*^u(#DK z*yRpq6NRNpqn#d;x@k%k#9x&{c&{Oe>W!%nFyphKXWq9Xi3V>0NNyP!^(7FpY6W_C zs#y@W9OwdYKD`PqVxaMz(h>yeH%bD$fqdj5*l#j8wIo-#~DH64VJJPM;C)KqX5r&gZFQ&+7O1Q3B0N^79Y zw_0vsp4x{z_3Gy7G8njp?)M1{SnQL991^&0UL0y_6PSrn-i_GBY+{C!1Ud|ZGa)T8 z1ZdFX{P>GF_CT#h_V7-Bf^4)~t-}E^ZDd7r-SMEU@R;RQ=~A%Is+F^vzhfuK3O z6O}866^It}M)goiVy<;*>67I34#MOo=@wM*hc^nwlgf!To0S46Ik*Fft$iZyWmP8K zUgt9Q;2b~sQC8WNTkK3P*wmLj4Ma8i`g{M z)cFfCEp(vsc=_jkZv;VJ)Z2hKxR?E58#K7~x>A04V~<}}Uw@8yjF&T^n1Z`*!68+- zhC2IBmR6-A`?gvu_H@Qvphm3|i2t?#gZPFl#Ww{O#D^$Gto0@rw`Fi48b%_~`P8!! z>uO&XEaU6UP4)Om-wLtPRX?h{6CEs2{kuKz4GA_XnXtujE#OqWE2|;Zz(vkX&N++?&Fx4mtbzQ9uMTV8IDmZmjxRQiK6w_PW zNU(Ra^uqf_8~~gNJhGtpe-G^hP6dlYn-45H;2q2q@R2E>;@yYX+{WQY!i1EKhtG2l z1T<@o8$xy^Cv*ey>xWsF!O{tWX4fQ>QuxAy#FfLOr$?2cNqb4fB%-=((l_9 z85Yd*Lvd6UB(Y-OlO$$^9We^^4|l->zwc0!1jJGJW3Fh9h=e6$!=NF=`olf zjh2Kt1&o7fPOH)&e7pYjFZHyDluvuWtSDult<@B`^Oa0YvBS9st@8#HWfX8wQ z%jP`ot2E%m5Y6Pr(`eOA9YheK2SK7fF_DrQ;N1@I%&PKbINVQdeTtw~kv4E9VoAg0 z%cDSZrMaJ6-uatA!chC+EOS%f5W5%@;yk~xDtKiVqG?KiYr*VsFn3BjxXU}0EvKu6 zw1!j068E}MVy4e%mt`W1Mzq_lMTUUG)}ZSOhV~Vy2bc0`?F^J0r;C>~RRa=-mFxU} zS)y=y!s+1b&nJw{OlAL~U2fcoFoFre1_>&LNQUGzqH`HkCwxOujEHE3%vZREuuGC#7_ zHkOg;9cA;D8il;H3bTWFQNF6lKvdw=yCz&?^1QhAnb%?-4wW_Zi?Aom-!&j38mw|> z*xM1q@Q>8W(OX+LeaS){q#>-9n=vOY{;gHb)PV-XoHq6FFCp~hK; zIf6dg}S9)!wn&z zNe2bhj`vNUIt!J`FNJ9XlbPFewBw7}B~;oaxJJ_jCJ6@{X`;YlMy0+94#Cxt$3D-J ziad@%mdOA6C?)~=<46el`@UD*VVcH|17uvuxyw$16zzvQO64q?+DrGG&!p`JbFDv& zPmEY>fpoMa<>8}U{5G*+7RIX;R zHjD$!!Jhat(deHcR|)5dT9z5*Kmc`qUL4x(3A-;X z@S||Nj+;{r*1ZN{$Wg`khdkH*)qp-tt5H??`0Q0-v`H7 z+9Tfda5-|w4jkhZs}As}`S4u8{32i+$^qpSL~mYD*CuZWTcP))m@Yc>GZQ&JO7|+m zGjE#6GfrKPA<_H8&kf_a_AfpCi^Yco)(Uf6ofU^A{A)t%_^hc-sH5p$9m1FFfFjZ_ zJ1%4sbUYtodu_T%=Y3GH)x^SfXR^i1`2>7{$hKU?@f|hGN9$heQ2hX%19&_MLmOvR zLZs=g1R18^ZzyL|vOx3oCRSXw;u!+x6fQ?FjzKHEKj$DT%yb(pX-S;{jp4#(+kZ}| z=UaNm5T41y^zl&I3`Ot>jKuCC!M3#cIU#w0QV5n#z^GU4TK%6=+H3ssho$yIXd?vv z?`K93xPBxhg0lnyC!C^W+0>NX#ywg<^u`<+QI|zT zu?BCvORsYLbc|2$dn-dLC?FW>X;d7yl13#yg>WX}>SIhbkf2X~hJuU*Tp^qNeB~Y) zc#ZJC_1;=W3cJso;t_PqC$t67WXSwqXaV-aJoZml+ZP($hSa%%G38OeW!0lW6RDf1 zd}sk7_Bamy#FxnS4pf0z69mz)-@lY>oMIl0Vin~ed~1m74In{o<#ol7>(5MS~`KF%F?iuoIm$ zQ?Y_-{O`}mR1EiA453#GUGwxnWSg-LBn%xG@U}FWhzbptY}^I%2XcboS@3sC~o50xT5lv7G@>CP9L)a=;)F;xun z>EpugX9?OQYj60#;egd-v!$@Jcvo!Lyh!+k#kc$}&bWkfKJU0={#&)))ZBBf{ltN4 zn}2|>JAPez#yq3HJ5mCKacw-tZ;_WBgBQ3YOY8c^u~nc)$)@G4l{mZiIq40k%#+-( z-zB4cvHuUa&C|@*oIl`hnYlU9Zq;M~PxCXC**GXrDv%GguQ^7x=Tyf#F%_o@!jL4Z z`=B=3C@AMg`mPn;6xlGc?Vc-wqIl_wUtgSQ)X_^m0jZ+Wahsw;p}d;S?cS)H(^1kK zMca|#fz7LDJj-#!noyyjZ;#XCPgl5}gVBV_O%v<=RSC=0jU@Hha{yFl@Z=z((~Z=3 z`p_O}u04!1&%ea}GBbiA*00Ay(t7obCOX_@i&xRO;8b8x=AlQCV z@hZw5UmnfP;~J6EfJ(=Lo#pJm9Wr`MI`z}v!%WFBFQkUKuY*A;T{GNp&7WB*QRRw9 zS`9!f(;xVwcQ?gjOvxjdNL;EAkZIQvShI#~kpaLnPvOUjh=Z6qr_!;k>FtI1c^!sV zD;{MmT&x8yJr)-X5CTYAcSwG+%0&sGsd~Z@zu8nghTzwtcGg}mr)N~tJOTYzm&jPYOIrzz}S2%kBbm?p1m>9SBRE$iHsKj zalymzUj+Axm-r`#ReCE*wkGyh8Unq0Ak{RrjY?m$S7VN0-4!ty0(fsBn`7kjsAutIB1uG5%0vZJX1QbrB5 bbk%CodkTaJdi?|lMO>vHj=(qZ0s;sCFmpR9 literal 0 HcmV?d00001 diff --git a/test/certs/private-key.pem b/test/certs/private-key.pem new file mode 100644 index 000000000..ba3c59928 --- /dev/null +++ b/test/certs/private-key.pem @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQCy7R51ycnO7edK +NgJYc6WqGT/NZfNAWHxBn/MKJTa5TF8yezN9l+4Ruarknapbq1EktS/YZJe02qm6 +uH7Ihq2V/7PvJ5GA0X52glOpxR+YL8CnAmzyclQmCobmC9Kqilo3pPqK5J69z+mu +yeg2/noOh7l5TxS5f/yTcGK0wWLWsprWqnpOJjcsVF5Rav+A11gwnug4zIXcXQOe +rwf98heKiHWyo4V7siLDbzDixLCXu3O7QPuxNefebzl/oxEUgEg5+6gN9dLXPfzS +JqGx89XxQQ98C/1ljI320TyzwtS0jNfBGKNwp/Zg7x8V8vxh2KvQDeT+3rENFpiA +NwAGUdJlCAzhkxtpBSBpaPbEkQSfmIG3++3AgPVhPHKgLBIGo0/WUEcWLRhScivz +PJkpXUvpNEzMllkdMFHhHZJxmk532MfJVy3FBY1jOpU3SWpuJXq3l+6pKCZcQmnR +zw6VvgyBOeXTkfT1b1SbQDnjFWbTHu73qEFuADGRY1fO60Cnc5kGBLtYS1sgzpeO +kAPVPJ2YWHPQOUxhjA1MIb7HKDUOw41LfztvSC/5/cKWmt4QPyt2nYOoZki+exwU +eDsT0XzS0+HO+8xMk06qSvb9JuVBnCichZu4EKRvTAHQowgNSX81lyy5AP1rM+zl +aaWJoR+/nWsMCygQBwtW1KNolsd/EwIDAQABAoICADjgmZs13xoRlEGJ86rscFAn +IJoJe48L0cwGrXqfI8s5lNV2RoL5JeuqisGLwRjM18mEc0Yli/govmWlul/CODID +i85NVLqPXdUMTs4b5JQ7MdGlOr7DSy6gkAtW3MvrmQwxPJekXzXVfuJaOqAouuId +kP8X/W2OWtr/kdEF3IaFViVBIgnvqgBEfYsCKWBqlBU4nndXxIGta7Yoy7CVIZif +ElMMGiWdFeHsWazse3pwUzTGTnwht6iE0NFbI9XRhaQw9FYju7dCdDjVoPbxnSPI +28RCB3YdfQ9lqhc2qukOEJPIYkQwkGh1+vq+OC5ecxd7Iz1FyyBu+2FemnpnzipY +6DJ962a4DccnfiBa4hnth9IWeJG86l7YRg81AK8Q4APVf/Seeact/1H1XHxMmOLg +RNLb+gS7Qh+fVQd7GUBMhLug/3vhjLgrYI+RNoU+nNnYPETZ3HB1uNGg8yFLxA0m +AnRqf38Z7QBWoodYWjOSQoplV5N7YETwBr7WFnA7fJsY1UgsJ2WzuAV9g0zc13Sw +EG87yvBNX+LFnEHvIfVtgULKv/lDW4ap89jn/w0KCK1g9kkkkL3axk6wG5Yqn4LR +hjZ/COdMvR/pT/EZf0rMZNc7x8bcQaWYX3zk7tQ9g4cl2fRY/4F80O7C6JQP8hwe +hG18AkowyXby4ivrd9JJAoIBAQDso+p21ckzH6q9Fp1GeSevEvSPIbt6ieVN5nKM +TlZYYLgYcTPRrzLyMh7YlKhk1JnNXuE3D1OEFOhgW0H3sjCMxh0qd8C7ZUOoCsmX +ckH9EO5M6f1m1Dz66tV9jPiXh/XFFfk654jM1N3L7QLfNr//hz5RCd+x7dKb+7wy +P6z3KN5V0vK+quyIVkRq6KaHM34UkG95X0SpkL3Kvb6O0KgEuQuGV/PSDqkomdo4 +oi++JEM2IvmVHMNM9EjYOzEuzZBwGGJriQ+OYYTeI9Ek8oARq7Wy89pcCuek3TI3 +qPJKYnst3P7unUFAcvwti10rYU+1A2yfhffJ7+hyO9jHJCKPAoIBAQDBkHeIbxn1 +m6WyzX1VQSbWvtNfGY46p9i/uxBm6IP5f8pht1veqFNS0qrvKeakYCppphS/wIg/ +Pl+7sjScP5u7X8LvifozXfYcYXj9pr7KkS04N0XMY44hDh09xkCyAlPps76bLeUK +pwjSgNSgF9GYqemV6We1hoDORP9iEuDg3xw5qVVlw7tek6ejpxERWdBxj9n1Kzp+ +07O9MTvGVNmSq01OBivz5wUxY1cLffZjZHm1gpjV172Mc/0kLijGILLTjC3wmOIK +tXkBCN3DZYMI5qiQMFGO5K+zLBMQ6+bHnx9UZUpJYSDwm59vDqXPzU4YZVACPXbV +ETXtmo9o9g09AoIBAQDAkhO3aPo2lEqJXeHW+7kDi9VgtP6wFY94+VO2QfmaKfsm +SNj2hjBbT9YyQadXhnsy2UdFWz+HeMwxvZHNVECWDpKlgJZi6WFJWp36lIyGuER0 +auY/y+9j8b6SUSnrhkTGgb8z5D87EO79iH6RzygndZOMtxBG51ZAgXcBHThQWf20 +sdnAt6+Ms0cyCOmblJfBfFh62MAzjQol9osgBUT1svBh/yj3g968n5cqBzH69d+M +KqIYajO0aAbvkBvSDo6/6dgN0pfKMinB7DvCaWU2/Bj869yCko03aJn5GY8yYToE +dJcw7t+u5uO43HSRXLtUftjiaE7hEk6Cx5j9VbaZAoIBADstM54eeU1BXJMhh6O8 +22bjyDNW2MjN79IOGqGbjF2G2BSvvgKAa5jylxevM7glPlI2WDmXXxAWvaXggX0T +ZUUPrcUV5cw2ebuLgTXq+IFtiOma3Ff0R8uLSR1NsxG47HaSYT+H9HIhRu00Pc0D ++yw1JhiS1wYELPTi20DcjKuzCioGvvjxsiLj+Whq9yja0IMne3cc1DFZ/6Vjm+ay +oiHZBTVJZb6Xblr/B+mXhPA2E4+OcbNO1cBO5aFeC1EnRgSu4oyf8NtdR7UtRL8s +Fbdu7THH0+dfuueIHfwaYt+8ohNnNCLi8vMcYM3PKJozJiEHOEK3D9FsBZSyoA1y +y/ECggEAbIANbhunUjbEN+dOgbtmEk/5thR2tnySw+x9QnlqeoAmBgwPPRE2F0dt +mL83TJMmeSqn9nI26LLRDsQEUyGP8W4vTNKuYnpno8ID4WnDHbzzVX/nsSW9zFN2 +NlJyEOPj6yuaHoBJp5qvm8c+HS7cw0TI0Ze6+PJBMS+2FRAFmcZr8myzmG0ZHmK8 +u/4iBTvz3EEewmmDYBGlagOR3f4GfE4PGmH33kyLZ1Yudk9edvrWwp5elNCizqhP +7FYWhNDidMjVpf1nJ+l2tG5voa626flESufL2QdkzRICq1dRtB0xTroDYbDaRAIn +3Q5ijNV6CUa+Ka7Qg7FWESHFemt1gQ== +-----END PRIVATE KEY----- From eb55ae83564bdb29204978af3a7341f8b6fb6cc6 Mon Sep 17 00:00:00 2001 From: Derek Ho Date: Fri, 1 Dec 2023 13:31:18 -0500 Subject: [PATCH 19/32] [Main] Check in yarn.lock file in its current state and update cypress to version 13.6.0 (#1668) * Check in yarn.lock file in its current state Signed-off-by: Derek Ho * Run bootstrap Signed-off-by: Derek Ho * Add the latest version of Cypress 13 and update yarn lock file Signed-off-by: Ryan Liang --------- Signed-off-by: Derek Ho Signed-off-by: Ryan Liang Co-authored-by: Craig Perkins Co-authored-by: Ryan Liang <109499885+RyanL1997@users.noreply.github.com> Co-authored-by: Ryan Liang --- .gitignore | 1 - package.json | 2 +- yarn.lock | 5192 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 5193 insertions(+), 2 deletions(-) create mode 100644 yarn.lock diff --git a/.gitignore b/.gitignore index 45a42aca7..b561f9475 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,6 @@ node_modules /build/ target .eslintcache -yarn.lock /coverage/ .es/ yarn-error.log diff --git a/package.json b/package.json index eea00c4c7..06b726f60 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "@elastic/eslint-import-resolver-kibana": "link:../../packages/osd-eslint-import-resolver-opensearch-dashboards", "@testing-library/react-hooks": "^7.0.2", "@types/hapi__wreck": "^15.0.1", - "cypress": "^13.5.1", + "cypress": "^13.6.0", "cypress-mochawesome-reporter": "^3.3.0", "gulp-rename": "2.0.0", "jose": "^4.11.2", diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 000000000..e4dbcd2ee --- /dev/null +++ b/yarn.lock @@ -0,0 +1,5192 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@auth0/thumbprint@0.0.6": + version "0.0.6" + resolved "https://registry.yarnpkg.com/@auth0/thumbprint/-/thumbprint-0.0.6.tgz#cab1062c6c04662ce6c592d48157ec4268ae8518" + integrity sha512-+YciWHxNUOE78T+xoXI1fMI6G1WdyyAay8ioaMZhvGOJ+lReYzj0b7mpfNr5WtjGrmtWPvPOOxh0TO+5Y2M/Hw== + +"@auth0/xmldom@0.1.21": + version "0.1.21" + resolved "https://registry.yarnpkg.com/@auth0/xmldom/-/xmldom-0.1.21.tgz#1db0a079c3ddc87bf9c13f35d9d4f0fb1dac3afc" + integrity sha512-//QqjkvBknF7j0Nf205o5wgUMnq8ioHHxEr61OZQ3J0RXGFvs2rb5GLZ8jdNxMqYz4n/PEsbFIQL5RHBixxq5g== + +"@babel/runtime@^7.12.5": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.4.tgz#36fa1d2b36db873d25ec631dcc4923fdc1cf2e2e" + integrity sha512-2Yv65nlWnWlSpe3fXEyX5i7fx5kIKo4Qbcj+hMO0odwaneFjfXw5fdum+4yL20O0QiaHpia0cYQ9xpNMqrBwHg== + dependencies: + regenerator-runtime "^0.14.0" + +"@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@^3.0.0": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@cypress/request/-/request-3.0.1.tgz#72d7d5425236a2413bd3d8bb66d02d9dc3168960" + integrity sha512-TWivJlJi8ZDx2wGOw1dbLuHJKUYX7bWySw377nlnGOW3hP9/MUKIsEdXT/YngWxVdgNCHRBmFlBipE+5/2ZZlQ== + 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.10.4" + safe-buffer "^5.1.2" + tough-cookie "^4.1.3" + 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" + +"@elastic/eslint-import-resolver-kibana@link:../../packages/osd-eslint-import-resolver-opensearch-dashboards": + version "0.0.0" + uid "" + +"@hapi/boom@*": + version "10.0.1" + resolved "https://registry.yarnpkg.com/@hapi/boom/-/boom-10.0.1.tgz#ebb14688275ae150aa6af788dbe482e6a6062685" + integrity sha512-ERcCZaEjdH3OgSJlyjVk8pHIFeus91CjKP3v+MpgBNp5IvGzP2l/bRiD78nqYcKPaZdbKkK5vDBVPd2ohHBlsA== + dependencies: + "@hapi/hoek" "^11.0.2" + +"@hapi/boom@9.x.x": + version "9.1.4" + resolved "https://registry.yarnpkg.com/@hapi/boom/-/boom-9.1.4.tgz#1f9dad367c6a7da9f8def24b4a986fc5a7bd9db6" + integrity sha512-Ls1oH8jaN1vNsqcaHVYJrKmgMcKsC1wcp8bujvXrHaAqD2iDYq3HoOwsxwo09Cuda5R5nC0o0IxlrlTuvPuzSw== + dependencies: + "@hapi/hoek" "9.x.x" + +"@hapi/bourne@2.x.x": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@hapi/bourne/-/bourne-2.1.0.tgz#66aff77094dc3080bd5df44ec63881f2676eb020" + integrity sha512-i1BpaNDVLJdRBEKeJWkVO6tYX6DMFBuwMhSuWqLsY4ufeTKGVuV5rBsUhxPayXqnnWHgXUAmWK16H/ykO5Wj4Q== + +"@hapi/cryptiles@5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@hapi/cryptiles/-/cryptiles-5.0.0.tgz#364ca3336594c7f261707a527c4d36da4a8eb86e" + integrity sha512-Yq43ti9N51Z7jbm0Q7YVCcofA+4Gh5wsBX/jZ++Z+FM8GYfBQ1WmI9ufZSL+BVX8vRxzDkdQ2fKoG6cxOQlnVQ== + dependencies: + "@hapi/boom" "9.x.x" + +"@hapi/hoek@9.x.x": + version "9.3.0" + resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.3.0.tgz#8368869dcb735be2e7f5cb7647de78e167a251fb" + integrity sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ== + +"@hapi/hoek@^11.0.2": + version "11.0.2" + resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-11.0.2.tgz#cb3ea547daac7de5c9cf1d960c3f35c34f065427" + integrity sha512-aKmlCO57XFZ26wso4rJsW4oTUnrgTFw2jh3io7CAtO9w4UltBNwRXvXIVzzyfkaaLRo3nluP/19msA8vDUUuKw== + +"@hapi/wreck@^17.1.0": + version "17.2.0" + resolved "https://registry.yarnpkg.com/@hapi/wreck/-/wreck-17.2.0.tgz#a5b69b724fa8fa25550fb02f55c649becfc59f63" + integrity sha512-pJ5kjYoRPYDv+eIuiLQqhGon341fr2bNIYZjuotuPJG/3Ilzr/XtI+JAp0A86E2bYfsS3zBPABuS2ICkaXFT8g== + dependencies: + "@hapi/boom" "9.x.x" + "@hapi/bourne" "2.x.x" + "@hapi/hoek" "9.x.x" + +"@node-rs/xxhash-android-arm-eabi@1.4.2": + version "1.4.2" + resolved "https://registry.yarnpkg.com/@node-rs/xxhash-android-arm-eabi/-/xxhash-android-arm-eabi-1.4.2.tgz#936b6b9b78035e1d136dd7bdf8296ad31fe1f4af" + integrity sha512-6aonl3wNY/axTiW9jSz+Z2RduP2xCZTgX1M1ur8uCJcUVv/kkv+dEMFb3o/k19qBGntPWvGXZTj2mYO6onDr/g== + +"@node-rs/xxhash-android-arm64@1.4.2": + version "1.4.2" + resolved "https://registry.yarnpkg.com/@node-rs/xxhash-android-arm64/-/xxhash-android-arm64-1.4.2.tgz#4a51efb021ffeaad9c36ec85e21233166e27c17c" + integrity sha512-Uhwsk3mp++Op2Sl/TzR1VfFqHx5sGMAwQGhQKThc/w8QSrDNfWKd1R9rjohIDWeNbmRguUCDPEKEOZwGewWacw== + +"@node-rs/xxhash-darwin-arm64@1.4.2": + version "1.4.2" + resolved "https://registry.yarnpkg.com/@node-rs/xxhash-darwin-arm64/-/xxhash-darwin-arm64-1.4.2.tgz#f51f02ccc0dd734db171c75a00a3cc0b2aceb595" + integrity sha512-0JYLJQ9C8prYbPPr3WlScYnAgIxLwitUwx2FnxNmBNH9bCDFoMdFXylzlxdYPHEYcXMsvWWcOnf9cESBH0WqzA== + +"@node-rs/xxhash-darwin-x64@1.4.2": + version "1.4.2" + resolved "https://registry.yarnpkg.com/@node-rs/xxhash-darwin-x64/-/xxhash-darwin-x64-1.4.2.tgz#cf70a5c5558dd825c1eb67e497f6c4dd1f0cc1ca" + integrity sha512-9CMuC7PZqHDaPCnOUrW6AIL+2gzLq22klGKBRXHXVfUELuNEqp7N0HyHheoQ99U0otCNnsA54zkfBw9cL1pcIA== + +"@node-rs/xxhash-freebsd-x64@1.4.2": + version "1.4.2" + resolved "https://registry.yarnpkg.com/@node-rs/xxhash-freebsd-x64/-/xxhash-freebsd-x64-1.4.2.tgz#5ce9441127fab0709189ccef5a24c328a0de233d" + integrity sha512-pPvuivkR3oyZ6DocgX6LSN2GpgF6Z4DK8M0UwDlY5P2wAUoi1JIOJBLjOrQmiaCUIIGCTTDBKTPwgIDUh6A7mg== + +"@node-rs/xxhash-linux-arm-gnueabihf@1.4.2": + version "1.4.2" + resolved "https://registry.yarnpkg.com/@node-rs/xxhash-linux-arm-gnueabihf/-/xxhash-linux-arm-gnueabihf-1.4.2.tgz#897e5612782279aff7d45b1a1a09e68f5b9709b6" + integrity sha512-LzI9WMW2scTG3/87/9j+oE0njz1o/2s7c61h1rEZyP1WBGA1cZ2xn3wAnwqFOPKE3s7QvONXoYjMMqa+BtDNNg== + +"@node-rs/xxhash-linux-arm64-gnu@1.4.2": + version "1.4.2" + resolved "https://registry.yarnpkg.com/@node-rs/xxhash-linux-arm64-gnu/-/xxhash-linux-arm64-gnu-1.4.2.tgz#46417a0253efd4d0b972f1b501d269590036a109" + integrity sha512-BeOlxfDzdnYRfK0nEyG8gpA6AGpamZVe2FNBl96xB5eVYiPp8PhIFLFsfoPURqa/Abm8+JV+QHzf3sngD1Gr+Q== + +"@node-rs/xxhash-linux-arm64-musl@1.4.2": + version "1.4.2" + resolved "https://registry.yarnpkg.com/@node-rs/xxhash-linux-arm64-musl/-/xxhash-linux-arm64-musl-1.4.2.tgz#3ea61d8236c0a36316130d167075a838508a47e7" + integrity sha512-u6l7mE5jmEWwUghZbfVHhhN9pMDkE0pjxjZu52bd8Ohk8LkbFDOJVNG2AWkWkjdInP31PmhvtCgE2laKCCQeRQ== + +"@node-rs/xxhash-linux-x64-gnu@1.4.2": + version "1.4.2" + resolved "https://registry.yarnpkg.com/@node-rs/xxhash-linux-x64-gnu/-/xxhash-linux-x64-gnu-1.4.2.tgz#6165e3a5db08f88a0c47ad4d93ab464212e5ecad" + integrity sha512-h3FUuuDBGdJ42HgA9lxX9cNSussF1lO/04OKXkVuJGRPR6mBCqBZ9SPNhzSk2PyYEqHimXIBYr+CdDRCS1xsfQ== + +"@node-rs/xxhash-linux-x64-musl@1.4.2": + version "1.4.2" + resolved "https://registry.yarnpkg.com/@node-rs/xxhash-linux-x64-musl/-/xxhash-linux-x64-musl-1.4.2.tgz#6668fd667f25cd2ff60a7f15e406e2e0cb5c9b56" + integrity sha512-W3/lMn1IBeTAcYVJEycxeyiMLD05M7OGsCZLAE0PB/t8dC+tH5jayVrYRhj+ZznK3V3pZfZb7cCVvZD2eCMb3g== + +"@node-rs/xxhash-win32-arm64-msvc@1.4.2": + version "1.4.2" + resolved "https://registry.yarnpkg.com/@node-rs/xxhash-win32-arm64-msvc/-/xxhash-win32-arm64-msvc-1.4.2.tgz#674fad808e8569ebd75f38fb22f9bee119864bda" + integrity sha512-53WhZY+khV/d8qmbLimCLXptq6/r1KD61Hi8I96KWxP6WiDl7Himhi5Pm2SbA2YK1WA3xPCaHj/LkPRks8Zi2g== + +"@node-rs/xxhash-win32-ia32-msvc@1.4.2": + version "1.4.2" + resolved "https://registry.yarnpkg.com/@node-rs/xxhash-win32-ia32-msvc/-/xxhash-win32-ia32-msvc-1.4.2.tgz#8b5b47051c555516fcc23c232497c5af42d31489" + integrity sha512-F1gWrwrNmw9rjxGphsDw9iGttXDEaGnAAj9U14+9n3WREMsmCRsKfoSZ41ln9KHH8hEABsxL15Tiutm++S3LmA== + +"@node-rs/xxhash-win32-x64-msvc@1.4.2": + version "1.4.2" + resolved "https://registry.yarnpkg.com/@node-rs/xxhash-win32-x64-msvc/-/xxhash-win32-x64-msvc-1.4.2.tgz#6dc64bd8e3461398e2caebe6b895b687bee9a80c" + integrity sha512-d7CUKK3IFYbED/0w6RosCKWL/RODfmA6yMfQdu3BZvh9Y8GTjRLE+DAIOOklP9Rb9qkKYSyzp2ALrHSkrHdRXQ== + +"@node-rs/xxhash@^1.3.0": + version "1.4.2" + resolved "https://registry.yarnpkg.com/@node-rs/xxhash/-/xxhash-1.4.2.tgz#91e4c74db14e7f078c06359a2ff2f85c3a24b84d" + integrity sha512-PvFTpG5z8tdXdZNkHUpjHDnBAKLxn6Xwp4yH8nfuVA2NcO3J970IHnm9yWcs9VVNwLr2aJx0lb8OvBAuLUNiEw== + optionalDependencies: + "@node-rs/xxhash-android-arm-eabi" "1.4.2" + "@node-rs/xxhash-android-arm64" "1.4.2" + "@node-rs/xxhash-darwin-arm64" "1.4.2" + "@node-rs/xxhash-darwin-x64" "1.4.2" + "@node-rs/xxhash-freebsd-x64" "1.4.2" + "@node-rs/xxhash-linux-arm-gnueabihf" "1.4.2" + "@node-rs/xxhash-linux-arm64-gnu" "1.4.2" + "@node-rs/xxhash-linux-arm64-musl" "1.4.2" + "@node-rs/xxhash-linux-x64-gnu" "1.4.2" + "@node-rs/xxhash-linux-x64-musl" "1.4.2" + "@node-rs/xxhash-win32-arm64-msvc" "1.4.2" + "@node-rs/xxhash-win32-ia32-msvc" "1.4.2" + "@node-rs/xxhash-win32-x64-msvc" "1.4.2" + +"@testing-library/react-hooks@^7.0.2": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@testing-library/react-hooks/-/react-hooks-7.0.2.tgz#3388d07f562d91e7f2431a4a21b5186062ecfee0" + integrity sha512-dYxpz8u9m4q1TuzfcUApqi8iFfR6R0FaMbr2hjZJy1uC8z+bO/K4v8Gs9eogGKYQop7QsrBTFkv/BCF7MzD2Cg== + dependencies: + "@babel/runtime" "^7.12.5" + "@types/react" ">=16.9.0" + "@types/react-dom" ">=16.9.0" + "@types/react-test-renderer" ">=16.9.0" + react-error-boundary "^3.1.0" + +"@types/hapi__boom@*": + version "9.0.1" + resolved "https://registry.yarnpkg.com/@types/hapi__boom/-/hapi__boom-9.0.1.tgz#8fbf719d0358e361b831802fb05fb4feced2ac29" + integrity sha512-TSqwgnTmNNp3/9uOpV16S8IVJv+QDmZLEImSuQrzGLCzmuK5P3bx3wdaXGXxfWLlN09Qqnd27POLrEAKhVCM5g== + dependencies: + "@hapi/boom" "*" + +"@types/hapi__wreck@^15.0.1": + version "15.0.1" + resolved "https://registry.yarnpkg.com/@types/hapi__wreck/-/hapi__wreck-15.0.1.tgz#41df4e122c49316f0057cb5e9c6eb4c00e671e95" + integrity sha512-OXhOaFWPFkWkqU5IlFwgTK/Q3yzc3iDhC1/S+3rQ6d2qkl6xvcRZaayJGjDXORf3krnGtDN1l3bIajNcuUl6QA== + dependencies: + "@types/hapi__boom" "*" + "@types/node" "*" + +"@types/node-forge@^1.3.0": + version "1.3.10" + resolved "https://registry.yarnpkg.com/@types/node-forge/-/node-forge-1.3.10.tgz#62a19d4f75a8b03290578c2b04f294b1a5a71b07" + integrity sha512-y6PJDYN4xYBxwd22l+OVH35N+1fCYWiuC3aiP2SlXVE6Lo7SS+rSx9r89hLxrP4pn6n1lBGhHJ12pj3F3Mpttw== + dependencies: + "@types/node" "*" + +"@types/node@*": + version "20.10.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.10.0.tgz#16ddf9c0a72b832ec4fcce35b8249cf149214617" + integrity sha512-D0WfRmU9TQ8I9PFx9Yc+EBHw+vSpIub4IDvQivcp26PtPrdMGAq5SDcpXEo/epqa/DXotVpekHiLNTg3iaKXBQ== + dependencies: + undici-types "~5.26.4" + +"@types/node@^18.17.5": + version "18.18.14" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.18.14.tgz#26771c647f2842af57eb96191cd615d845164295" + integrity sha512-iSOeNeXYNYNLLOMDSVPvIFojclvMZ/HDY2dU17kUlcsOsSQETbWIslJbYLZgA+ox8g2XQwSHKTkght1a5X26lQ== + dependencies: + undici-types "~5.26.4" + +"@types/prop-types@*": + version "15.7.11" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.11.tgz#2596fb352ee96a1379c657734d4b913a613ad563" + integrity sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng== + +"@types/react-dom@>=16.9.0": + version "18.2.17" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.17.tgz#375c55fab4ae671bd98448dcfa153268d01d6f64" + integrity sha512-rvrT/M7Df5eykWFxn6MYt5Pem/Dbyc1N8Y0S9Mrkw2WFCRiqUgw9P7ul2NpwsXCSM1DVdENzdG9J5SreqfAIWg== + dependencies: + "@types/react" "*" + +"@types/react-test-renderer@>=16.9.0": + version "18.0.7" + resolved "https://registry.yarnpkg.com/@types/react-test-renderer/-/react-test-renderer-18.0.7.tgz#2cfe657adb3688cdf543995eceb2e062b5a68728" + integrity sha512-1+ANPOWc6rB3IkSnElhjv6VLlKg2dSv/OWClUyZimbLsQyBn8Js9Vtdsi3UICJ2rIQ3k2la06dkB+C92QfhKmg== + dependencies: + "@types/react" "*" + +"@types/react@*", "@types/react@>=16.9.0": + version "18.2.39" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.39.tgz#744bee99e053ad61fe74eb8b897f3ab5b19a7e25" + integrity sha512-Oiw+ppED6IremMInLV4HXGbfbG6GyziY3kqAwJYOR0PNbkYDmLWQA3a95EhdSmamsvbkJN96ZNN+YD+fGjzSBA== + dependencies: + "@types/prop-types" "*" + "@types/scheduler" "*" + csstype "^3.0.2" + +"@types/scheduler@*": + version "0.16.8" + resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.8.tgz#ce5ace04cfeabe7ef87c0091e50752e36707deff" + integrity sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A== + +"@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.8" + resolved "https://registry.yarnpkg.com/@types/sizzle/-/sizzle-2.3.8.tgz#518609aefb797da19bf222feb199e8f653ff7627" + integrity sha512-0vWLNK2D5MT9dg0iOo8GlKguPAU02QjmZitPEsXRuJXU/OGIOt9vT9Fc26wtYuavLxtO45v9PGleoL9Z0k1LHg== + +"@types/yauzl@^2.9.1": + version "2.10.3" + resolved "https://registry.yarnpkg.com/@types/yauzl/-/yauzl-2.10.3.tgz#e9b2808b4f109504a03cda958259876f61017999" + integrity sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q== + dependencies: + "@types/node" "*" + +"@webassemblyjs/ast@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964" + integrity sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA== + dependencies: + "@webassemblyjs/helper-module-context" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/wast-parser" "1.9.0" + +"@webassemblyjs/floating-point-hex-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz#3c3d3b271bddfc84deb00f71344438311d52ffb4" + integrity sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA== + +"@webassemblyjs/helper-api-error@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz#203f676e333b96c9da2eeab3ccef33c45928b6a2" + integrity sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw== + +"@webassemblyjs/helper-buffer@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz#a1442d269c5feb23fcbc9ef759dac3547f29de00" + integrity sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA== + +"@webassemblyjs/helper-code-frame@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz#647f8892cd2043a82ac0c8c5e75c36f1d9159f27" + integrity sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA== + dependencies: + "@webassemblyjs/wast-printer" "1.9.0" + +"@webassemblyjs/helper-fsm@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz#c05256b71244214671f4b08ec108ad63b70eddb8" + integrity sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw== + +"@webassemblyjs/helper-module-context@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz#25d8884b76839871a08a6c6f806c3979ef712f07" + integrity sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g== + dependencies: + "@webassemblyjs/ast" "1.9.0" + +"@webassemblyjs/helper-wasm-bytecode@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz#4fed8beac9b8c14f8c58b70d124d549dd1fe5790" + integrity sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw== + +"@webassemblyjs/helper-wasm-section@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz#5a4138d5a6292ba18b04c5ae49717e4167965346" + integrity sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + +"@webassemblyjs/ieee754@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz#15c7a0fbaae83fb26143bbacf6d6df1702ad39e4" + integrity sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg== + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.9.0.tgz#f19ca0b76a6dc55623a09cffa769e838fa1e1c95" + integrity sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw== + dependencies: + "@xtuc/long" "4.2.2" + +"@webassemblyjs/utf8@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.9.0.tgz#04d33b636f78e6a6813227e82402f7637b6229ab" + integrity sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w== + +"@webassemblyjs/wasm-edit@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz#3fe6d79d3f0f922183aa86002c42dd256cfee9cf" + integrity sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/helper-wasm-section" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + "@webassemblyjs/wasm-opt" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + "@webassemblyjs/wast-printer" "1.9.0" + +"@webassemblyjs/wasm-gen@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz#50bc70ec68ded8e2763b01a1418bf43491a7a49c" + integrity sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/ieee754" "1.9.0" + "@webassemblyjs/leb128" "1.9.0" + "@webassemblyjs/utf8" "1.9.0" + +"@webassemblyjs/wasm-opt@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz#2211181e5b31326443cc8112eb9f0b9028721a61" + integrity sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + +"@webassemblyjs/wasm-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz#9d48e44826df4a6598294aa6c87469d642fff65e" + integrity sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-api-error" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/ieee754" "1.9.0" + "@webassemblyjs/leb128" "1.9.0" + "@webassemblyjs/utf8" "1.9.0" + +"@webassemblyjs/wast-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz#3031115d79ac5bd261556cecc3fa90a3ef451914" + integrity sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/floating-point-hex-parser" "1.9.0" + "@webassemblyjs/helper-api-error" "1.9.0" + "@webassemblyjs/helper-code-frame" "1.9.0" + "@webassemblyjs/helper-fsm" "1.9.0" + "@xtuc/long" "4.2.2" + +"@webassemblyjs/wast-printer@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz#4935d54c85fef637b00ce9f52377451d00d47899" + integrity sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/wast-parser" "1.9.0" + "@xtuc/long" "4.2.2" + +"@xmldom/xmldom@^0.7.0", "@xmldom/xmldom@^0.7.4", "@xmldom/xmldom@^0.7.9": + version "0.7.13" + resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.7.13.tgz#ff34942667a4e19a9f4a0996a76814daac364cf3" + integrity sha512-lm2GW5PkosIzccsaZIz7tp8cPADSIlIHWDFTR1N0SzfinhhYgeIQjFMz4rYzanCScr3DqQLeomUDArp6MWKm+g== + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.2": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" + integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== + +accepts@~1.3.8: + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== + dependencies: + mime-types "~2.1.34" + negotiator "0.6.3" + +acorn@^6.4.1: + version "6.4.2" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6" + integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ== + +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: + clean-stack "^2.0.0" + indent-string "^4.0.0" + +ajv-errors@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" + integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ== + +ajv-keywords@^3.1.0, ajv-keywords@^3.4.1: + version "3.5.2" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" + integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== + +ajv@^6.1.0, ajv@^6.10.2: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ansi-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@^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" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +anymatch@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== + dependencies: + micromatch "^3.1.4" + normalize-path "^2.1.1" + +anymatch@~3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +aproba@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== + +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== + +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA== + +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-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q== + +array-buffer-byte-length@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz#fabe8bc193fea865f317fe7807085ee0dee5aead" + integrity sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A== + dependencies: + call-bind "^1.0.2" + is-array-buffer "^3.0.1" + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== + +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + integrity sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ== + +array.prototype.find@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/array.prototype.find/-/array.prototype.find-2.2.2.tgz#e862cf891e725d8f2a10e5e42d750629faaabd32" + integrity sha512-DRumkfW97iZGOfn+lIXbkVrXL04sfYKX+EfOodo8XboR5sxPDVvOjZTF/rysusa9lmhmSOeD6Vp6RKQP+eP4Tg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + es-shim-unscopables "^1.0.0" + +arraybuffer.prototype.slice@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz#98bd561953e3e74bb34938e77647179dfe6e9f12" + integrity sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw== + dependencies: + array-buffer-byte-length "^1.0.0" + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + get-intrinsic "^1.2.1" + is-array-buffer "^3.0.2" + is-shared-array-buffer "^1.0.2" + +asn1.js@^5.2.0: + version "5.4.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-5.4.1.tgz#11a980b84ebb91781ce35b0fdc2ee294e3783f07" + integrity sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA== + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + safer-buffer "^2.1.0" + +asn1@~0.2.3: + version "0.2.6" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d" + integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ== + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw== + +assert@^1.1.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.1.tgz#038ab248e4ff078e7bc2485ba6e6388466c78f76" + integrity sha512-zzw1uCAgLbsKwBfFc8CX78DDg+xZeBksSO3vwVIDDN5i94eOrPsSSyiVhmsSABFDM/OcpE2aagCat9dnWQLG1A== + dependencies: + object.assign "^4.1.4" + util "^0.10.4" + +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw== + +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-each@^1.0.1: + version "1.0.6" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.6.tgz#52f1d9403818c179b7561e11a5d1b77eb2160e77" + integrity sha512-c646jH1avxr+aVpndVMeAfYw7wAa6idufrlN3LPA4PmKS0QEGp6PIC9nwz0WQkkvBGAMEki3pFdtxaF39J9vvg== + +async@^3.2.0: + version "3.2.5" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.5.tgz#ebd52a8fdaf7a2289a24df399f8d8485c8a46b66" + integrity sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg== + +async@~0.2.9: + version "0.2.10" + resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1" + integrity sha512-eAkdoKxU6/LkKDBzLpT+t6Ff5EtfSF4wx1WfJiPEEV7WNLnDaRXk0oVysiEPm262roaachGexwUv94WhSgN5TQ== + +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== + +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== + +atob@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + +auth0-id-generator@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/auth0-id-generator/-/auth0-id-generator-0.2.0.tgz#abf27b501710f47451978de833e52035fd439e0c" + integrity sha512-sJVZrGls/XB7TEsAovv6GsGwsjDBhBy014w+9x/DNZH8OTV8F/uioMmT68ADWtfbvfkJaNCYNjRs1dOVFyNqbQ== + +available-typed-arrays@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" + integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA== + +aws4@^1.8.0: + version "1.12.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.12.0.tgz#ce1c9d143389679e253b314241ea9aa5cec980d3" + integrity sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg== + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +base64-js@^1.0.2, base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + +basic-auth@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/basic-auth/-/basic-auth-2.0.1.tgz#b998279bf47ce38344b4f3cf916d4679bbf51e3a" + integrity sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg== + dependencies: + safe-buffer "5.1.2" + +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w== + dependencies: + tweetnacl "^0.14.3" + +big.js@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" + integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== + +binary-extensions@^1.0.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" + integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== + +binary-extensions@^2.0.0: + version "2.2.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== + +bluebird@^3.5.5, 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== + +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.9: + version "4.12.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" + integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== + +bn.js@^5.0.0, bn.js@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" + integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== + +body-parser@1.20.1: + version "1.20.1" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668" + integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw== + dependencies: + bytes "3.1.2" + content-type "~1.0.4" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.11.0" + raw-body "2.5.1" + type-is "~1.6.18" + unpipe "1.0.0" + +body-parser@~1.19.0: + version "1.19.2" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.2.tgz#4714ccd9c157d44797b8b5607d72c0b89952f26e" + integrity sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw== + dependencies: + bytes "3.1.2" + content-type "~1.0.4" + debug "2.6.9" + depd "~1.1.2" + http-errors "1.8.1" + iconv-lite "0.4.24" + on-finished "~2.3.0" + qs "6.9.7" + raw-body "2.4.3" + type-is "~1.6.18" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^2.3.1, braces@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + +braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +brorand@^1.0.1, brorand@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== + +browserify-aes@^1.0.0, browserify-aes@^1.0.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" + integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== + dependencies: + buffer-xor "^1.0.3" + cipher-base "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.3" + inherits "^2.0.1" + safe-buffer "^5.0.1" + +browserify-cipher@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" + integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== + dependencies: + browserify-aes "^1.0.4" + browserify-des "^1.0.0" + evp_bytestokey "^1.0.0" + +browserify-des@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" + integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== + dependencies: + cipher-base "^1.0.1" + des.js "^1.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +browserify-rsa@^4.0.0, browserify-rsa@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.1.0.tgz#b2fd06b5b75ae297f7ce2dc651f918f5be158c8d" + integrity sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog== + dependencies: + bn.js "^5.0.0" + randombytes "^2.0.1" + +browserify-sign@^4.0.0: + version "4.2.2" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.2.2.tgz#e78d4b69816d6e3dd1c747e64e9947f9ad79bc7e" + integrity sha512-1rudGyeYY42Dk6texmv7c4VcQ0EsvVbLwZkA+AQB7SxvXxmcD93jcHie8bzecJ+ChDlmAm2Qyu0+Ccg5uhZXCg== + dependencies: + bn.js "^5.2.1" + browserify-rsa "^4.1.0" + create-hash "^1.2.0" + create-hmac "^1.1.7" + elliptic "^6.5.4" + inherits "^2.0.4" + parse-asn1 "^5.1.6" + readable-stream "^3.6.2" + safe-buffer "^5.2.1" + +browserify-zlib@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" + integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA== + dependencies: + pako "~1.0.5" + +buffer-crc32@~0.2.3: + version "0.2.13" + resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" + integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ== + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +buffer-xor@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + integrity sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ== + +buffer@^4.3.0: + version "4.9.2" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" + integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.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== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + +builtin-status-codes@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" + integrity sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ== + +bytes@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== + +cacache@^12.0.2: + version "12.0.4" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.4.tgz#668bcbd105aeb5f1d92fe25570ec9525c8faa40c" + integrity sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ== + dependencies: + bluebird "^3.5.5" + chownr "^1.1.1" + figgy-pudding "^3.5.1" + glob "^7.1.4" + graceful-fs "^4.1.15" + infer-owner "^1.0.3" + lru-cache "^5.1.1" + mississippi "^3.0.0" + mkdirp "^0.5.1" + move-concurrently "^1.0.1" + promise-inflight "^1.0.1" + rimraf "^2.6.3" + ssri "^6.0.1" + unique-filename "^1.1.1" + y18n "^4.0.0" + +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + +cachedir@^2.3.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/cachedir/-/cachedir-2.4.0.tgz#7fef9cf7367233d7c88068fe6e34ed0d355a610d" + integrity sha512-9EtFOZR8g22CL7BWjJ9BUx1+A/djkofnyW3aOXZORNW2kxoUpx2h+uN2cOqwPmFhnpVmxg+KW2OjOSgChTEvsQ== + +call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.4, call-bind@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.5.tgz#6fa2b7845ce0ea49bf4d8b9ef64727a2c2e2e513" + integrity sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ== + dependencies: + function-bind "^1.1.2" + get-intrinsic "^1.2.1" + set-function-length "^1.1.1" + +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== + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw== + +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" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +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@^2.1.8: + version "2.1.8" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" + integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== + dependencies: + anymatch "^2.0.0" + async-each "^1.0.1" + braces "^2.3.2" + glob-parent "^3.1.0" + inherits "^2.0.3" + is-binary-path "^1.0.0" + is-glob "^4.0.0" + normalize-path "^3.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.2.1" + upath "^1.1.1" + optionalDependencies: + fsevents "^1.2.7" + +chokidar@^3.4.1: + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + 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== + +chrome-trace-event@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" + integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== + +ci-info@^3.2.0: + version "3.9.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4" + integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== + +cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +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@^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@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" + integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg== + +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== + +colorette@^2.0.16: + version "2.0.20" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" + integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== + +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" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +commander@^10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06" + integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug== + +commander@^2.20.0: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commander@^6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" + integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== + +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== + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== + +component-emitter@^1.2.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.1.tgz#ef1d5796f7d93f135ee6fb684340b26403c97d17" + integrity sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +concat-stream@^1.5.0: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +console-browserify@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" + integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== + +constants-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" + integrity sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ== + +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + +content-type@~1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" + integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== + +cookie@0.4.2: + version "0.4.2" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" + integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== + +cookie@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" + integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== + +copy-concurrently@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" + integrity sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A== + dependencies: + aproba "^1.1.1" + fs-write-stream-atomic "^1.0.8" + iferr "^0.1.5" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.0" + +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== + +core-util-is@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ== + +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + +create-ecdh@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e" + integrity sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A== + dependencies: + bn.js "^4.1.0" + elliptic "^6.5.3" + +create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + md5.js "^1.3.4" + ripemd160 "^2.0.1" + sha.js "^2.4.0" + +create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== + dependencies: + cipher-base "^1.0.3" + create-hash "^1.1.0" + inherits "^2.0.1" + ripemd160 "^2.0.0" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +cross-spawn@^7.0.0: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +crypto-browserify@^3.11.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" + integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== + dependencies: + browserify-cipher "^1.0.0" + browserify-sign "^4.0.0" + create-ecdh "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.0" + diffie-hellman "^5.0.0" + inherits "^2.0.1" + pbkdf2 "^3.0.3" + public-encrypt "^4.0.0" + randombytes "^2.0.0" + randomfill "^1.0.3" + +csstype@^3.0.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b" + integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ== + +cyclist@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.2.tgz#673b5f233bf34d8e602b949429f8171d9121bea3" + integrity sha512-0sVXIohTfLqVIW3kb/0n6IiWF3Ifj5nm2XaSrLq2DI6fKIGa2fYAZdk917rUneaeLVpYfFcyXE2ft0fe3remsA== + +cypress-mochawesome-reporter@^3.3.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/cypress-mochawesome-reporter/-/cypress-mochawesome-reporter-3.7.0.tgz#a32570ba896862a1a6e7443ad5bbd71baf7c2ba4" + integrity sha512-aeC5hpYJ/cS0M1PvIBfkyW3+yNIOgrFrI+ijEZZxsovGWqhSankCcias88igjiyzc+6mjFWnIXsd5NuRVF5nwA== + dependencies: + commander "^10.0.1" + fs-extra "^10.0.1" + mochawesome "^7.1.3" + mochawesome-merge "^4.2.1" + mochawesome-report-generator "^6.2.0" + +cypress@^13.6.0: + version "13.6.0" + resolved "https://registry.yarnpkg.com/cypress/-/cypress-13.6.0.tgz#b98b7b837679012ed09c7ecee5565bf7b31d4982" + integrity sha512-quIsnFmtj4dBUEJYU4OH0H12bABJpSujvWexC24Ju1gTlKMJbeT6tTO0vh7WNfiBPPjoIXLN+OUqVtiKFs6SGw== + dependencies: + "@cypress/request" "^3.0.0" + "@cypress/xvfb" "^1.2.4" + "@types/node" "^18.17.5" + "@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 "^6.2.1" + common-tags "^1.8.0" + dayjs "^1.10.4" + debug "^4.3.4" + 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.8" + ospath "^1.2.2" + pretty-bytes "^5.6.0" + process "^0.11.10" + proxy-from-env "1.0.0" + request-progress "^3.0.0" + semver "^7.5.3" + 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" + integrity sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g== + dependencies: + assert-plus "^1.0.0" + +dateformat@^4.5.1: + version "4.6.3" + resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-4.6.3.tgz#556fa6497e5217fedb78821424f8a1c22fa3f4b5" + integrity sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA== + +dayjs@^1.10.4: + version "1.11.10" + resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.10.tgz#68acea85317a6e164457d6d6947564029a6a16a0" + integrity sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ== + +debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.9: + 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.1.0, debug@^3.2.7: + 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" + +debug@^4.1.1, debug@^4.3.4: + 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@~4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" + integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== + 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== + +decode-uri-component@^0.2.0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9" + integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ== + +define-data-property@^1.0.1, define-data-property@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.1.tgz#c35f7cd0ab09883480d12ac5cb213715587800b3" + integrity sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ== + dependencies: + get-intrinsic "^1.2.1" + gopd "^1.0.1" + has-property-descriptors "^1.0.0" + +define-properties@^1.1.3, define-properties@^1.1.4, define-properties@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" + integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== + dependencies: + define-data-property "^1.0.1" + has-property-descriptors "^1.0.0" + object-keys "^1.1.1" + +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== + +depd@2.0.0, depd@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== + +des.js@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.1.0.tgz#1d37f5766f3bbff4ee9638e871a8768c173b81da" + integrity sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg== + dependencies: + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +destroy@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" + integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== + +diff@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-5.1.0.tgz#bc52d298c5ea8df9194800224445ed43ffc87e40" + integrity sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw== + +diffie-hellman@^5.0.0: + version "5.0.3" + resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" + integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== + dependencies: + bn.js "^4.1.0" + miller-rabin "^4.0.0" + randombytes "^2.0.0" + +domain-browser@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" + integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== + +duplexify@^3.4.2, duplexify@^3.6.0: + version "3.7.1" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" + integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== + dependencies: + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw== + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== + +ejs@2.5.5: + version "2.5.5" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.5.5.tgz#6ef4e954ea7dcf54f66aad2fe7aa421932d9ed77" + integrity sha512-SVMZ8TKYCxHL6gb7f9QVpvnMPxZpdrT65IH6awbFex+bVAWtEYW0LoRbiViOJn6t1v/J0tVrl9fx6XOuJ5fjTA== + +elliptic@^6.5.3, elliptic@^6.5.4: + version "6.5.4" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" + integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== + dependencies: + bn.js "^4.11.9" + brorand "^1.1.0" + hash.js "^1.0.0" + hmac-drbg "^1.0.1" + inherits "^2.0.4" + minimalistic-assert "^1.0.1" + minimalistic-crypto-utils "^1.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== + +emojis-list@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" + integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== + +end-of-stream@^1.0.0, 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" + +enhanced-resolve@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-0.9.1.tgz#4d6e689b3725f86090927ccc86cd9f1635b89e2e" + integrity sha512-kxpoMgrdtkXZ5h0SeraBS1iRntpTpQ3R8ussdb38+UAFnMGX5DDyJXePm+OCHOcoXvHDw7mc2erbJBpDnl7TPw== + dependencies: + graceful-fs "^4.1.2" + memory-fs "^0.2.0" + tapable "^0.1.8" + +enhanced-resolve@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz#2f3cfd84dbe3b487f18f2db2ef1e064a571ca5ec" + integrity sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg== + dependencies: + graceful-fs "^4.1.2" + memory-fs "^0.5.0" + tapable "^1.0.0" + +enquirer@^2.3.6: + version "2.4.1" + resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.4.1.tgz#93334b3fbd74fc7097b224ab4a8fb7e40bf4ae56" + integrity sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ== + dependencies: + ansi-colors "^4.1.1" + strip-ansi "^6.0.1" + +errno@^0.1.3, errno@~0.1.7: + version "0.1.8" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" + integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A== + dependencies: + prr "~1.0.1" + +es-abstract@^1.22.1: + version "1.22.3" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.22.3.tgz#48e79f5573198de6dee3589195727f4f74bc4f32" + integrity sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA== + dependencies: + array-buffer-byte-length "^1.0.0" + arraybuffer.prototype.slice "^1.0.2" + available-typed-arrays "^1.0.5" + call-bind "^1.0.5" + es-set-tostringtag "^2.0.1" + es-to-primitive "^1.2.1" + function.prototype.name "^1.1.6" + get-intrinsic "^1.2.2" + get-symbol-description "^1.0.0" + globalthis "^1.0.3" + gopd "^1.0.1" + has-property-descriptors "^1.0.0" + has-proto "^1.0.1" + has-symbols "^1.0.3" + hasown "^2.0.0" + internal-slot "^1.0.5" + is-array-buffer "^3.0.2" + is-callable "^1.2.7" + is-negative-zero "^2.0.2" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.2" + is-string "^1.0.7" + is-typed-array "^1.1.12" + is-weakref "^1.0.2" + object-inspect "^1.13.1" + object-keys "^1.1.1" + object.assign "^4.1.4" + regexp.prototype.flags "^1.5.1" + safe-array-concat "^1.0.1" + safe-regex-test "^1.0.0" + string.prototype.trim "^1.2.8" + string.prototype.trimend "^1.0.7" + string.prototype.trimstart "^1.0.7" + typed-array-buffer "^1.0.0" + typed-array-byte-length "^1.0.0" + typed-array-byte-offset "^1.0.0" + typed-array-length "^1.0.4" + unbox-primitive "^1.0.2" + which-typed-array "^1.1.13" + +es-set-tostringtag@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz#11f7cc9f63376930a5f20be4915834f4bc74f9c9" + integrity sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q== + dependencies: + get-intrinsic "^1.2.2" + has-tostringtag "^1.0.0" + hasown "^2.0.0" + +es-shim-unscopables@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz#1f6942e71ecc7835ed1c8a83006d8771a63a3763" + integrity sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw== + dependencies: + hasown "^2.0.0" + +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== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-html@^1.0.3, escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== + +eslint-import-resolver-node@0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz#58f15fb839b8d0576ca980413476aab2472db66a" + integrity sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q== + dependencies: + debug "^2.6.9" + resolve "^1.5.0" + +eslint-import-resolver-webpack@0.13.8: + version "0.13.8" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-webpack/-/eslint-import-resolver-webpack-0.13.8.tgz#5f64d1d653eefa19cdfd0f0165c996b6be7012f9" + integrity sha512-Y7WIaXWV+Q21Rz/PJgUxiW/FTBOWmU8NTLdz+nz9mMoiz5vAev/fOaQxwD7qRzTfE3HSm1qsxZ5uRd7eX+VEtA== + dependencies: + array.prototype.find "^2.2.2" + debug "^3.2.7" + enhanced-resolve "^0.9.1" + find-root "^1.1.0" + hasown "^2.0.0" + interpret "^1.4.0" + is-core-module "^2.13.1" + is-regex "^1.1.4" + lodash "^4.17.21" + resolve "^2.0.0-next.5" + semver "^5.7.2" + +eslint-plugin-cypress@^2.8.1: + version "2.15.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-cypress/-/eslint-plugin-cypress-2.15.1.tgz#336afa7e8e27451afaf65aa359c9509e0a4f3a7b" + integrity sha512-eLHLWP5Q+I4j2AWepYq0PgFEei9/s5LvjuSqWrxurkg1YZ8ltxdvMNmdSf0drnsNo57CTgYY/NIHHLRSWejR7w== + dependencies: + globals "^13.20.0" + +eslint-scope@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" + integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg== + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +esrecurse@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== + +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== + +events@^3.0.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + +evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" + integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== + dependencies: + md5.js "^1.3.4" + safe-buffer "^5.1.1" + +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" + +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA== + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +express-session@^1.17.1: + version "1.17.3" + resolved "https://registry.yarnpkg.com/express-session/-/express-session-1.17.3.tgz#14b997a15ed43e5949cb1d073725675dd2777f36" + integrity sha512-4+otWXlShYlG1Ma+2Jnn+xgKUZTMJ5QD3YvfilX3AcocOAbIkVylSWEklzALe/+Pu4qV6TYBj5GwOBFfdKqLBw== + dependencies: + cookie "0.4.2" + cookie-signature "1.0.6" + debug "2.6.9" + depd "~2.0.0" + on-headers "~1.0.2" + parseurl "~1.3.3" + safe-buffer "5.2.1" + uid-safe "~2.1.5" + +express@^4.17.1: + version "4.18.2" + resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59" + integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ== + dependencies: + accepts "~1.3.8" + array-flatten "1.1.1" + body-parser "1.20.1" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.5.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "2.0.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.2.0" + fresh "0.5.2" + http-errors "2.0.0" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "2.4.1" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.7" + qs "6.11.0" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.18.0" + serve-static "1.15.0" + setprototypeof "1.2.0" + statuses "2.0.1" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +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" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q== + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +extend@^3.0.2, extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +extract-zip@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-2.0.1.tgz#663dca56fe46df890d5f131ef4a06d22bb8ba13a" + integrity sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg== + dependencies: + debug "^4.1.1" + get-stream "^5.1.0" + yauzl "^2.10.0" + optionalDependencies: + "@types/yauzl" "^2.9.1" + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g== + +extsprintf@^1.2.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07" + integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== + +fast-deep-equal@^3.1.1: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fd-slicer@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" + integrity sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g== + dependencies: + pend "~1.2.0" + +figgy-pudding@^3.5.1: + version "3.5.2" + resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e" + integrity sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw== + +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-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@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ== + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +finalhandler@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" + integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "2.4.1" + parseurl "~1.3.3" + statuses "2.0.1" + unpipe "~1.0.0" + +find-cache-dir@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" + integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ== + dependencies: + commondir "^1.0.1" + make-dir "^2.0.0" + pkg-dir "^3.0.0" + +find-root@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4" + integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng== + +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.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== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +flowstate@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/flowstate/-/flowstate-0.4.1.tgz#b5fbb8b7fc2d7bdc5b54be46c98309ef736f4ec0" + integrity sha512-U67AgveyMwXFIiDgs6Yz/PrUNrZGLJUUMDwJ9Q0fDFTQSzyDg8Jj9YDyZIUnFZKggQZONVueK9+grp/Gxa/scw== + dependencies: + clone "^1.0.2" + uid-safe "^2.1.0" + utils-flatten "^1.0.0" + +flush-write-stream@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" + integrity sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w== + dependencies: + inherits "^2.0.3" + readable-stream "^2.3.6" + +for-each@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" + integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== + dependencies: + is-callable "^1.1.3" + +for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ== + +foreachasync@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/foreachasync/-/foreachasync-3.0.0.tgz#5502987dc8714be3392097f32e0071c9dee07cf6" + integrity sha512-J+ler7Ta54FwwNcx6wQRDhTIbNeyDcARMkOcguEqnEdtm0jKvN3Li3PDAb2Du3ubJYEWfYL83XMROXdsXAXycw== + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw== + +form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA== + dependencies: + map-cache "^0.2.2" + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== + +from2@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" + integrity sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g== + dependencies: + inherits "^2.0.1" + readable-stream "^2.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== + dependencies: + graceful-fs "^4.2.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-write-stream-atomic@^1.0.8: + version "1.0.10" + resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" + integrity sha512-gehEzmPn2nAwr39eay+x3X34Ra+M2QlVUTLhkXPjWdeO8RF9kszk116avgBJM3ZyNHgHXBNx+VmPaFC36k0PzA== + dependencies: + graceful-fs "^4.1.2" + iferr "^0.1.5" + imurmurhash "^0.1.4" + readable-stream "1 || 2" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@^1.2.7: + version "1.2.13" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.13.tgz#f325cb0455592428bcf11b383370ef70e3bfcc38" + integrity sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw== + dependencies: + bindings "^1.5.0" + nan "^2.12.1" + +fsevents@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + +fsu@^1.1.1: + version "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.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== + +function.prototype.name@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.6.tgz#cdf315b7d90ee77a4c6ee216c3c3362da07533fd" + integrity sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + functions-have-names "^1.2.3" + +functions-have-names@^1.2.3: + 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.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-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1, get-intrinsic@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.2.tgz#281b7622971123e1ef4b3c90fd7539306da93f3b" + integrity sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA== + dependencies: + function-bind "^1.1.2" + has-proto "^1.0.1" + has-symbols "^1.0.3" + hasown "^2.0.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== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.1" + +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + integrity sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA== + +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: + async "^3.2.0" + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng== + dependencies: + assert-plus "^1.0.0" + +glob-all@^3.2.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/glob-all/-/glob-all-3.3.1.tgz#6be2d5d8276902319f640fbf839fbe15b35e7667" + integrity sha512-Y+ESjdI7ZgMwfzanHZYQ87C59jOO0i+Hd+QYtVt9PhLi6d8wlOpzQnfBxWUlaTuAoR3TkybLqqbIoWveU4Ji7Q== + dependencies: + glob "^7.2.3" + yargs "^15.3.1" + +glob-parent@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + integrity sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA== + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + +glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, glob@^7.2.3: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +global-dirs@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-3.0.1.tgz#0c488971f066baceda21447aecb1a8b911d22485" + integrity sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA== + dependencies: + ini "2.0.0" + +globals@^13.20.0: + version "13.23.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.23.0.tgz#ef31673c926a0976e1f61dab4dca57e0c0a8af02" + integrity sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA== + dependencies: + type-fest "^0.20.2" + +globalthis@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.3.tgz#5852882a52b80dc301b0660273e1ed082f0b6ccf" + integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA== + dependencies: + define-properties "^1.1.3" + +gopd@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" + integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== + dependencies: + get-intrinsic "^1.1.3" + +graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0: + version "4.2.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + +gulp-rename@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/gulp-rename/-/gulp-rename-2.0.0.tgz#9bbc3962b0c0f52fc67cd5eaff6c223ec5b9cf6c" + integrity sha512-97Vba4KBzbYmR5VBs9mWmK+HwIf5mj+/zioxfZhOKeXtx5ZjBk57KFlePf5nxq9QsTtFl0ejnHE3zTC9MHXqyQ== + +handlebars@4.7.7: + version "4.7.7" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1" + integrity sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA== + dependencies: + minimist "^1.2.5" + neo-async "^2.6.0" + source-map "^0.6.1" + wordwrap "^1.0.0" + optionalDependencies: + uglify-js "^3.1.4" + +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@^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.1" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz#52ba30b6c5ec87fd89fa574bc1c39125c6f65340" + integrity sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg== + dependencies: + get-intrinsic "^1.2.2" + +has-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" + integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== + +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-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q== + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw== + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ== + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ== + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +hash-base@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" + integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== + dependencies: + inherits "^2.0.4" + readable-stream "^3.6.0" + safe-buffer "^5.2.0" + +hash.js@^1.0.0, hash.js@^1.0.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + +hasown@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.0.tgz#f4c513d454a57b7c7e1650778de226b11700546c" + integrity sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA== + dependencies: + function-bind "^1.1.2" + +hbs@^4.1.1: + version "4.2.0" + resolved "https://registry.yarnpkg.com/hbs/-/hbs-4.2.0.tgz#10e40dcc24d5be7342df9636316896617542a32b" + integrity sha512-dQwHnrfWlTk5PvG9+a45GYpg0VpX47ryKF8dULVd6DtwOE6TEcYQXQ5QM6nyOx/h7v3bvEQbdn19EDAcfUAgZg== + dependencies: + handlebars "4.7.7" + walk "2.3.15" + +hmac-drbg@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg== + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + +html-entities@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.3.1.tgz#fb9a1a4b5b14c5daba82d3e34c6ae4fe701a0e44" + integrity sha512-rhE/4Z3hIhzHAUKbW8jVcCyuT5oJCXXqhN/6mXXVCpzTmvJnoH2HL/bt3EZ6p55jbFJBeAe1ZNpL5BugLujxNA== + +http-errors@1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.8.1.tgz#7c3f28577cbc8a207388455dbd62295ed07bd68c" + integrity sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g== + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.1" + +http-errors@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" + integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== + dependencies: + depd "2.0.0" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses "2.0.1" + toidentifier "1.0.1" + +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 "^2.0.2" + sshpk "^1.14.1" + +https-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" + integrity sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg== + +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== + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +ieee754@^1.1.13, ieee754@^1.1.4: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + +iferr@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" + integrity sha512-DUNFN5j7Tln0D+TxzloUjKB+CtVu6myn0JEFak6dG18mNt9YkQ6lzGCdafwofISZ1lLF3xRHJ98VKy9ynkcFaA== + +immediate@~3.0.5: + version "3.0.6" + resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" + integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ== + +imurmurhash@^0.1.4: + version "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== + +infer-owner@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" + integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== + +ini@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ini/-/ini-2.0.0.tgz#e5fd556ecdd5726be978fa1001862eacb0a94bc5" + integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA== + +internal-slot@^1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.6.tgz#37e756098c4911c5e912b8edbf71ed3aa116f930" + integrity sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg== + dependencies: + get-intrinsic "^1.2.2" + hasown "^2.0.0" + side-channel "^1.0.4" + +interpret@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" + integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== + +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +is-accessor-descriptor@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.1.tgz#3223b10628354644b86260db29b3e693f5ceedd4" + integrity sha512-YBUanLI8Yoihw923YeFUS5fs0fF2f5TSFTNiYAAzhhDscDa3lEqYuz1pDOEP5KvX94I9ey3vsqjJcLVFVU+3QA== + dependencies: + hasown "^2.0.0" + +is-array-buffer@^3.0.1, is-array-buffer@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.2.tgz#f2653ced8412081638ecb0ebbd0c41c6e0aecbbe" + integrity sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.0" + is-typed-array "^1.1.10" + +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" + +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + integrity sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q== + dependencies: + binary-extensions "^1.0.0" + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + 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-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-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" + integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== + +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: + ci-info "^3.2.0" + +is-core-module@^2.13.0, is-core-module@^2.13.1: + version "2.13.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384" + integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw== + dependencies: + hasown "^2.0.0" + +is-data-descriptor@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.1.tgz#2109164426166d32ea38c405c1e0945d9e6a4eeb" + integrity sha512-bc4NlCDiCr28U4aEsQ3Qs2491gVq4V8G7MQyws968ImqjKuYtTJXrl7Vq7jsN7Ly/C3xj5KWFrY7sHNeDkAzXw== + dependencies: + hasown "^2.0.0" + +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== + dependencies: + has-tostringtag "^1.0.0" + +is-descriptor@^0.1.0: + version "0.1.7" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.7.tgz#2727eb61fd789dcd5bdf0ed4569f551d2fe3be33" + integrity sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg== + dependencies: + is-accessor-descriptor "^1.0.1" + is-data-descriptor "^1.0.1" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.3.tgz#92d27cb3cd311c4977a4db47df457234a13cb306" + integrity sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw== + dependencies: + is-accessor-descriptor "^1.0.1" + is-data-descriptor "^1.0.1" + +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-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== + dependencies: + is-plain-object "^2.0.4" + +is-extglob@^2.1.0, is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +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-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + integrity sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw== + dependencies: + is-extglob "^2.1.0" + +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +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: + global-dirs "^3.0.0" + is-path-inside "^3.0.2" + +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== + dependencies: + has-tostringtag "^1.0.0" + +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@^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: + 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-object@^2.0.3, 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-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-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-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-typed-array@^1.1.10, is-typed-array@^1.1.12, is-typed-array@^1.1.9: + version "1.1.12" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.12.tgz#d0bab5686ef4a76f7a73097b95470ab199c57d4a" + integrity sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg== + dependencies: + which-typed-array "^1.1.11" + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== + +is-unicode-supported@^0.1.0: + version "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" + +is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== + +is-wsl@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" + integrity sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw== + +isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== + +isarray@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" + integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA== + dependencies: + isarray "1.0.0" + +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== + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g== + +jose@^4.11.2: + version "4.15.4" + resolved "https://registry.yarnpkg.com/jose/-/jose-4.15.4.tgz#02a9a763803e3872cf55f29ecef0dfdcc218cc03" + integrity sha512-W+oqK4H+r5sITxfxpSU+MMdr/YSWGvgZMQDIsNoBDGGy4i7GBPTtvFKibQzW06n3U3TqHjhvBJsirShsEJ6eeQ== + +"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" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg== + +json-parse-better-errors@^1.0.2: + 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" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" + integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== + +json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== + +json5@^2.1.2: + version "2.2.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== + +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" + integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== + dependencies: + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + +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" + +jszip@^3.10.1: + version "3.10.1" + resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.10.1.tgz#34aee70eb18ea1faec2f589208a157d1feb091c2" + integrity sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g== + dependencies: + lie "~3.3.0" + pako "~1.0.2" + readable-stream "~2.3.6" + setimmediate "^1.0.5" + +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + 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@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw== + dependencies: + is-buffer "^1.1.5" + +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== + +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== + +lie@~3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/lie/-/lie-3.3.0.tgz#dcf82dee545f46074daf200c7c1c5a08e0f40f6a" + integrity sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ== + dependencies: + immediate "~3.0.5" + +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" + +loader-runner@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" + integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw== + +loader-utils@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c" + integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^2.1.2" + +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +lodash.isempty@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.isempty/-/lodash.isempty-4.4.0.tgz#6f86cbedd8be4ec987be9aaf33c9684db1b31e7e" + integrity sha512-oKMuF3xEeqDltrGMfDxAPGIVMSSRv8tbRSODbrs4KGsRRLEhrW8N8Rd4DRgB2+621hY8A8XwwrTVhXWpxFvMzg== + +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.isobject@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/lodash.isobject/-/lodash.isobject-3.0.2.tgz#3c8fb8d5b5bf4bf90ae06e14f2a530a4ed935e1d" + integrity sha512-3/Qptq2vr7WeJbB4KHUSKlq8Pl7ASXi3UG6CMbBm8WRtXi8+GHm7mKaU3urfpSEzWe2wCIChs6/sdocUsTKJiA== + +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.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.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== + dependencies: + 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" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +lru-cache@^4.1.5: + version "4.1.5" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" + integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +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" + +make-dir@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" + integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== + dependencies: + pify "^4.0.1" + semver "^5.6.0" + +map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg== + +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" + +md5.js@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" + integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== + +memory-fs@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.2.0.tgz#f2bb25368bc121e391c2520de92969caee0a0290" + integrity sha512-+y4mDxU4rvXXu5UDSGCGNiesFmwCHuefGMoPCO1WYucNYj7DsLqrFaa2fXVI0H+NNiPTwwzKwspn9yTZqUGqng== + +memory-fs@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" + integrity sha512-cda4JKCxReDXFXRqOHPQscuIYg1PvxbE2S2GP45rnwfEK+vZaXC8C1OFvdHIbgw0DLzowXGVoxLaAmlgRy14GQ== + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + +memory-fs@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.5.0.tgz#324c01288b88652966d161db77838720845a8e3c" + integrity sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA== + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== + +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== + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== + +micromatch@^3.1.10, micromatch@^3.1.4: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + +miller-rabin@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" + integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== + dependencies: + bn.js "^4.0.0" + brorand "^1.0.1" + +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, mime-types@~2.1.19, mime-types@~2.1.24, mime-types@~2.1.34: + 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" + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +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== + +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg== + +minimatch@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimist@^1.2.5, minimist@^1.2.6, minimist@^1.2.8: + version "1.2.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + +mississippi@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" + integrity sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA== + dependencies: + concat-stream "^1.5.0" + duplexify "^3.4.2" + end-of-stream "^1.1.0" + flush-write-stream "^1.0.0" + from2 "^2.1.0" + parallel-transform "^1.1.0" + pump "^3.0.0" + pumpify "^1.3.3" + stream-each "^1.1.0" + through2 "^2.0.0" + +mixin-deep@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" + integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + +mkdirp@^0.5.1, mkdirp@^0.5.3: + version "0.5.6" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" + integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== + dependencies: + minimist "^1.2.6" + +mochawesome-merge@^4.2.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/mochawesome-merge/-/mochawesome-merge-4.3.0.tgz#7cc5d5730c7d8d1b034c8d8fecf3cd36e0010297" + integrity sha512-1roR6g+VUlfdaRmL8dCiVpKiaUhbPVm1ZQYUM6zHX46mWk+tpsKVZR6ba98k2zc8nlPvYd71yn5gyH970pKBSw== + 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" + integrity sha512-Ghw8JhQFizF0Vjbtp9B0i//+BOkV5OWcQCPpbO0NGOoxV33o+gKDYU0Pr2pGxkIHnqZ+g5mYiXF7GMNgAcDpSg== + dependencies: + chalk "^4.1.2" + dateformat "^4.5.1" + escape-html "^1.0.3" + fs-extra "^10.0.0" + fsu "^1.1.1" + lodash.isfunction "^3.0.9" + opener "^1.5.2" + prop-types "^15.7.2" + tcomb "^3.2.17" + tcomb-validation "^3.3.0" + validator "^13.6.0" + yargs "^17.2.1" + +mochawesome@^7.1.3: + version "7.1.3" + resolved "https://registry.yarnpkg.com/mochawesome/-/mochawesome-7.1.3.tgz#07b358138f37f5b07b51a1b255d84babfa36fa83" + integrity sha512-Vkb3jR5GZ1cXohMQQ73H3cZz7RoxGjjUo0G5hu0jLaW+0FdUxUwg3Cj29bqQdh0rFcnyV06pWmqmi5eBPnEuNQ== + dependencies: + chalk "^4.1.2" + diff "^5.0.0" + json-stringify-safe "^5.0.1" + lodash.isempty "^4.4.0" + lodash.isfunction "^3.0.9" + lodash.isobject "^3.0.2" + lodash.isstring "^4.0.1" + mochawesome-report-generator "^6.2.0" + strip-ansi "^6.0.1" + uuid "^8.3.2" + +moment@2.19.3: + version "2.19.3" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.19.3.tgz#bdb99d270d6d7fda78cc0fbace855e27fe7da69f" + integrity sha512-SiZ1HUDMfBpfCzL1Hm1vxUFkYDbHx8/RiWBLF+5qoVWTlBGtR15+wVQB7eSD/0w3ueDxzojlX9LQtiKVpLMsFQ== + +morgan@^1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.10.0.tgz#091778abc1fc47cd3509824653dae1faab6b17d7" + integrity sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ== + dependencies: + basic-auth "~2.0.1" + debug "2.6.9" + depd "~2.0.0" + on-finished "~2.3.0" + on-headers "~1.0.2" + +move-concurrently@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" + integrity sha512-hdrFxZOycD/g6A6SoI2bB5NA/5NEqD0569+S47WZhPvm46sD50ZHdYaFmnua5lndde9rCHGjmfK7Z8BuCt/PcQ== + dependencies: + aproba "^1.1.1" + copy-concurrently "^1.0.0" + fs-write-stream-atomic "^1.0.8" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.3" + +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.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.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +nan@^2.12.1: + version "2.18.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.18.0.tgz#26a6faae7ffbeb293a39660e88a76b82e30b7554" + integrity sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w== + +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + +neo-async@^2.5.0, neo-async@^2.6.0, neo-async@^2.6.1: + version "2.6.2" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== + +node-forge@^1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" + integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== + +node-libs-browser@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425" + integrity sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q== + dependencies: + assert "^1.1.1" + browserify-zlib "^0.2.0" + buffer "^4.3.0" + console-browserify "^1.1.0" + constants-browserify "^1.0.0" + crypto-browserify "^3.11.0" + domain-browser "^1.1.1" + events "^3.0.0" + https-browserify "^1.0.0" + os-browserify "^0.3.0" + path-browserify "0.0.1" + process "^0.11.10" + punycode "^1.2.4" + querystring-es3 "^0.2.0" + readable-stream "^2.3.3" + stream-browserify "^2.0.1" + stream-http "^2.7.2" + string_decoder "^1.0.0" + timers-browserify "^2.0.4" + tty-browserify "0.0.0" + url "^0.11.0" + util "^0.11.0" + vm-browserify "^1.0.1" + +normalize-path@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + integrity sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w== + dependencies: + remove-trailing-separator "^1.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-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: + 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-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-inspect@^1.13.1, object-inspect@^1.9.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2" + integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ== + +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-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" + +object.assign@^4.1.4: + version "4.1.4" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f" + integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + has-symbols "^1.0.3" + object-keys "^1.1.1" + +object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ== + dependencies: + isobject "^3.0.1" + +on-finished@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== + dependencies: + ee-first "1.1.1" + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww== + dependencies: + ee-first "1.1.1" + +on-headers@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" + integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== + +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" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + 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" + integrity sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A== + +os-browserify@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" + integrity sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A== + +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.0.0, p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +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@~1.0.2, pako@~1.0.5: + version "1.0.11" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" + integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== + +parallel-transform@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.2.0.tgz#9049ca37d6cb2182c3b1d2c720be94d14a5814fc" + integrity sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg== + dependencies: + cyclist "^1.0.1" + inherits "^2.0.3" + readable-stream "^2.1.5" + +parse-asn1@^5.0.0, parse-asn1@^5.1.6: + version "5.1.6" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.6.tgz#385080a3ec13cb62a62d39409cb3e88844cdaed4" + integrity sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw== + dependencies: + asn1.js "^5.2.0" + browserify-aes "^1.0.0" + evp_bytestokey "^1.0.0" + pbkdf2 "^3.0.3" + safe-buffer "^5.1.1" + +parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw== + +path-browserify@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a" + integrity sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ== + +path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + integrity sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q== + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ== + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +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-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== + +pbkdf2@^3.0.3: + version "3.1.2" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" + integrity sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA== + dependencies: + create-hash "^1.1.2" + create-hmac "^1.1.4" + ripemd160 "^2.0.1" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +pend@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" + integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg== + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow== + +picomatch@^2.0.4, picomatch@^2.2.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +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== + +pify@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" + integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== + +pkg-dir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" + integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== + dependencies: + find-up "^3.0.0" + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg== + +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== + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== + +promise-inflight@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" + integrity sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g== + +prop-types@^15.7.2: + version "15.8.1" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" + integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.13.1" + +proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + +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== + +prr@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" + integrity sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw== + +pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + integrity sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ== + +psl@^1.1.33: + version "1.9.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" + integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== + +public-encrypt@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" + integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== + dependencies: + bn.js "^4.1.0" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + parse-asn1 "^5.0.0" + randombytes "^2.0.1" + safe-buffer "^5.1.2" + +pump@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" + integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pumpify@^1.3.3: + version "1.5.1" + resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" + integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ== + dependencies: + duplexify "^3.6.0" + inherits "^2.0.3" + pump "^2.0.0" + +punycode@^1.2.4, punycode@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ== + +punycode@^2.1.0, punycode@^2.1.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" + integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== + +qs@6.10.4: + version "6.10.4" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.4.tgz#6a3003755add91c0ec9eacdc5f878b034e73f9e7" + integrity sha512-OQiU+C+Ds5qiH91qh/mg0w+8nwQuLjM4F4M/PbmhDOoYehPh+Fb0bDjtR1sOvy7YKxvj28Y/M0PhP5uVX0kB+g== + dependencies: + side-channel "^1.0.4" + +qs@6.11.0: + version "6.11.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" + integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== + dependencies: + side-channel "^1.0.4" + +qs@6.9.7: + version "6.9.7" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.7.tgz#4610846871485e1e048f44ae3b94033f0e675afe" + integrity sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw== + +qs@^6.11.2: + version "6.11.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.2.tgz#64bea51f12c1f5da1bc01496f48ffcff7c69d7d9" + integrity sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA== + dependencies: + side-channel "^1.0.4" + +querystring-es3@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" + integrity sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA== + +querystring@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.1.tgz#40d77615bb09d16902a85c3e38aa8b5ed761c2dd" + integrity sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg== + +querystringify@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" + integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== + +random-bytes@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/random-bytes/-/random-bytes-1.0.0.tgz#4f68a1dc0ae58bd3fb95848c30324db75d64360b" + integrity sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ== + +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +randomfill@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" + integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== + dependencies: + randombytes "^2.0.5" + safe-buffer "^5.1.0" + +range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.4.3: + version "2.4.3" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.3.tgz#8f80305d11c2a0a545c2d9d89d7a0286fcead43c" + integrity sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g== + dependencies: + bytes "3.1.2" + http-errors "1.8.1" + iconv-lite "0.4.24" + unpipe "1.0.0" + +raw-body@2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" + integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + +react-error-boundary@^3.1.0: + version "3.1.4" + resolved "https://registry.yarnpkg.com/react-error-boundary/-/react-error-boundary-3.1.4.tgz#255db92b23197108757a888b01e5b729919abde0" + integrity sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA== + dependencies: + "@babel/runtime" "^7.12.5" + +react-is@^16.13.1: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== + +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: + version "2.3.8" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" + integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^3.6.0, readable-stream@^3.6.2: + version "3.6.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readdirp@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" + integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== + dependencies: + graceful-fs "^4.1.11" + micromatch "^3.1.10" + readable-stream "^2.0.2" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +regenerator-runtime@^0.14.0: + version "0.14.0" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45" + integrity sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA== + +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + +regexp.prototype.flags@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz#90ce989138db209f81492edd734183ce99f9677e" + integrity sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + set-function-name "^2.0.0" + +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + integrity sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw== + +repeat-element@^1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.4.tgz#be681520847ab58c7568ac75fbfad28ed42d39e9" + integrity sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ== + +repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w== + +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: + 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== + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg== + +resolve@^1.5.0, resolve@^1.7.1: + version "1.22.8" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" + integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +resolve@^2.0.0-next.5: + version "2.0.0-next.5" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.5.tgz#6b0ec3107e671e52b68cd068ef327173b90dc03c" + integrity sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +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: + onetime "^5.1.0" + signal-exit "^3.0.2" + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== + +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@^2.5.4, rimraf@^2.6.3: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + +rimraf@^3.0.0: + 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" + +ripemd160@^2.0.0, ripemd160@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + +run-queue@^1.0.0, run-queue@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" + integrity sha512-ntymy489o0/QQplUDnpYAYUsO50K9SBrIVaKCWDOJzYJts0f9WH9RFJkyagebkw5+y1oi00R7ynNW/d12GBumg== + dependencies: + aproba "^1.1.1" + +rxjs@^7.5.1: + version "7.8.1" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543" + integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== + dependencies: + tslib "^2.1.0" + +safe-array-concat@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.0.1.tgz#91686a63ce3adbea14d61b14c99572a8ff84754c" + integrity sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.1" + has-symbols "^1.0.3" + isarray "^2.0.5" + +safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@^5.2.1, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-regex-test@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz#793b874d524eb3640d1873aad03596db2d4f2295" + integrity sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.3" + is-regex "^1.1.4" + +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg== + dependencies: + ret "~0.1.10" + +"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +saml-idp@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/saml-idp/-/saml-idp-1.2.1.tgz#2df394cd406ce273641115f587062ea60d29ce03" + integrity sha512-C7iXTxryohn8fOWUGyPDCJwyA4eWyh4gJrMAndyRe+idTrj51kPOW1FAAsIBc7afmoJLM00qqcAP/gxalq4r9A== + dependencies: + body-parser "~1.19.0" + chalk "^4.0.0" + debug "~4.1.1" + express "^4.17.1" + express-session "^1.17.1" + extend "^3.0.2" + hbs "^4.1.1" + morgan "^1.10.0" + samlp "github:mcguinness/node-samlp" + xml-formatter "^2.1.0" + xmldom "^0.3.0" + yargs "^15.3.1" + +"saml@github:mcguinness/node-saml": + version "3.0.0" + resolved "https://codeload.github.com/mcguinness/node-saml/tar.gz/6c1e1c823d94cb99245c93b70348bc648a419954" + dependencies: + "@xmldom/xmldom" "^0.7.4" + async "~0.2.9" + moment "2.19.3" + valid-url "~1.0.9" + xml-crypto "^2.1.3" + xml-encryption "^2.0.0" + xml-name-validator "~2.0.1" + xpath "0.0.5" + +"samlp@github:mcguinness/node-samlp": + version "7.0.1" + resolved "https://codeload.github.com/mcguinness/node-samlp/tar.gz/fb9653b3b74f1f5ec41a47c8b88191a5f7c1ebae" + dependencies: + "@auth0/thumbprint" "0.0.6" + "@auth0/xmldom" "0.1.21" + auth0-id-generator "^0.2.0" + ejs "2.5.5" + flowstate "^0.4.0" + querystring "^0.2.0" + saml "github:mcguinness/node-saml" + xml-crypto "^2.0.0" + xpath "0.0.5" + xtend "^1.0.3" + +schema-utils@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770" + integrity sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g== + dependencies: + ajv "^6.1.0" + ajv-errors "^1.0.0" + ajv-keywords "^3.1.0" + +selenium-webdriver@4.10.0: + version "4.10.0" + resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-4.10.0.tgz#0508cdfbb5ad8470d8fd19db1a69d3e87f474b79" + integrity sha512-hSQPw6jgc+ej/UEcdQPG/iBwwMeCEgZr9HByY/J8ToyXztEqXzU9aLsIyrlj1BywBcStO4JQK/zMUWWrV8+riA== + dependencies: + jszip "^3.10.1" + tmp "^0.2.1" + ws ">=8.13.0" + +selfsigned@^2.0.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.4.1.tgz#560d90565442a3ed35b674034cec4e95dceb4ae0" + integrity sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q== + dependencies: + "@types/node-forge" "^1.3.0" + node-forge "^1" + +semver@^5.6.0, semver@^5.7.2: + version "5.7.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" + integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== + +semver@^7.5.3: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + +send@0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" + integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== + dependencies: + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "2.0.0" + mime "1.6.0" + ms "2.1.3" + on-finished "2.4.1" + range-parser "~1.2.1" + statuses "2.0.1" + +serialize-javascript@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-4.0.0.tgz#b525e1238489a5ecfc42afacc3fe99e666f4b1aa" + integrity sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw== + dependencies: + randombytes "^2.1.0" + +serve-static@1.15.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" + integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.18.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== + +set-function-length@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.1.1.tgz#4bc39fafb0307224a33e106a7d35ca1218d659ed" + integrity sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ== + dependencies: + define-data-property "^1.1.1" + get-intrinsic "^1.2.1" + gopd "^1.0.1" + has-property-descriptors "^1.0.0" + +set-function-name@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/set-function-name/-/set-function-name-2.0.1.tgz#12ce38b7954310b9f61faa12701620a0c882793a" + integrity sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA== + dependencies: + define-data-property "^1.0.1" + functions-have-names "^1.2.3" + has-property-descriptors "^1.0.0" + +set-value@^2.0.0, set-value@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" + integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + +setimmediate@^1.0.4, setimmediate@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== + +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +sha.js@^2.4.0, sha.js@^2.4.8: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +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== + +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" + +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== + +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: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + +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: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + +source-list-map@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" + integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== + +source-map-resolve@^0.5.0: + version "0.5.3" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" + integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== + dependencies: + atob "^2.1.2" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-support@~0.5.12: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map-url@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56" + integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== + +source-map@^0.5.6: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== + +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== + dependencies: + extend-shallow "^3.0.0" + +sshpk@^1.14.1: + version "1.18.0" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.18.0.tgz#1663e55cddf4d688b86a46b77f0d5fe363aba028" + integrity sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ== + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + +ssri@^6.0.1: + version "6.0.2" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.2.tgz#157939134f20464e7301ddba3e90ffa8f7728ac5" + integrity sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q== + dependencies: + figgy-pudding "^3.5.1" + +static-extend@^0.1.1: + 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" + +statuses@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + +"statuses@>= 1.5.0 < 2": + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== + +stream-browserify@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b" + integrity sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg== + dependencies: + inherits "~2.0.1" + readable-stream "^2.0.2" + +stream-each@^1.1.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae" + integrity sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw== + dependencies: + end-of-stream "^1.1.0" + stream-shift "^1.0.0" + +stream-http@^2.7.2: + version "2.8.3" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" + integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw== + dependencies: + builtin-status-codes "^3.0.0" + inherits "^2.0.1" + readable-stream "^2.3.6" + to-arraybuffer "^1.0.0" + xtend "^4.0.0" + +stream-shift@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" + integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== + +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" + +string.prototype.trim@^1.2.8: + version "1.2.8" + resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz#f9ac6f8af4bd55ddfa8895e6aea92a96395393bd" + integrity sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + +string.prototype.trimend@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz#1bb3afc5008661d73e2dc015cd4853732d6c471e" + integrity sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + +string.prototype.trimstart@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz#d4cdb44b83a4737ffbac2d406e405d43d0184298" + integrity sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + +string_decoder@^1.0.0, 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" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.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-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== + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +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-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== + +tapable@^0.1.8: + version "0.1.10" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-0.1.10.tgz#29c35707c2b70e50d07482b5d202e8ed446dafd4" + integrity sha512-jX8Et4hHg57mug1/079yitEKWGB3LCwoxByLsNim89LABq8NqgiX+6iYVOsq0vX8uJHkU+DZ5fnq95f800bEsQ== + +tapable@^1.0.0, tapable@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" + integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== + +tcomb-validation@^3.3.0: + version "3.4.1" + resolved "https://registry.yarnpkg.com/tcomb-validation/-/tcomb-validation-3.4.1.tgz#a7696ec176ce56a081d9e019f8b732a5a8894b65" + integrity sha512-urVVMQOma4RXwiVCa2nM2eqrAomHROHvWPuj6UkDGz/eb5kcy0x6P0dVt6kzpUZtYMNoAqJLWmz1BPtxrtjtrA== + dependencies: + tcomb "^3.0.0" + +tcomb@^3.0.0, tcomb@^3.2.17: + version "3.2.29" + resolved "https://registry.yarnpkg.com/tcomb/-/tcomb-3.2.29.tgz#32404fe9456d90c2cf4798682d37439f1ccc386c" + integrity sha512-di2Hd1DB2Zfw6StGv861JoAF5h/uQVu/QJp2g8KVbtfKnoHdBQl5M32YWq6mnSYBQ1vFFrns5B1haWJL7rKaOQ== + +"terser-webpack-plugin@npm:@amoo-miki/terser-webpack-plugin@1.4.5-rc.2": + version "1.4.5-rc.2" + resolved "https://registry.yarnpkg.com/@amoo-miki/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5-rc.2.tgz#046c062ef22c126c2544718674bc6624e3651b9c" + integrity sha512-JFSGSzsWgSHEqQXlnHDh3gw+jdVdVlWM2Irdps9P/yWYNY/5VjuG8sdoW4mbuP8/HM893/k8N+ipbeqsd8/xpA== + dependencies: + "@node-rs/xxhash" "^1.3.0" + cacache "^12.0.2" + find-cache-dir "^2.1.0" + is-wsl "^1.1.0" + schema-utils "^1.0.0" + serialize-javascript "^4.0.0" + source-map "^0.6.1" + terser "^4.1.2" + webpack-sources "^1.4.0" + worker-farm "^1.7.0" + +terser@^4.1.2: + version "4.8.1" + resolved "https://registry.yarnpkg.com/terser/-/terser-4.8.1.tgz#a00e5634562de2239fd404c649051bf6fc21144f" + integrity sha512-4GnLC0x667eJG0ewJTa6z/yXrbLGv80D9Ru6HIpCQmO+Q4PfEtBFi0ObSckqwL6VyQv/7ENJieXHo2ANmdQwgw== + dependencies: + commander "^2.20.0" + source-map "~0.6.1" + source-map-support "~0.5.12" + +throttleit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-1.0.1.tgz#304ec51631c3b770c65c6c6f76938b384000f4d5" + integrity sha512-vDZpf9Chs9mAdfY046mcPt8fg5QSZr37hEH4TXYBnDF+izxgrbRGUAAaBvIk/fJm9aOFCGFd1EsNg5AZCbnQCQ== + +through2@^2.0.0: + version "2.0.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" + integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== + dependencies: + readable-stream "~2.3.6" + xtend "~4.0.1" + +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== + +timers-browserify@^2.0.4: + version "2.0.12" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.12.tgz#44a45c11fbf407f34f97bccd1577c652361b00ee" + integrity sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ== + dependencies: + setimmediate "^1.0.4" + +tmp@^0.2.1, 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-arraybuffer@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" + integrity sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA== + +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" + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + integrity sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg== + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +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" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + +tough-cookie@^4.1.3: + version "4.1.3" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.3.tgz#97b9adb0728b42280aa3d814b6b999b2ff0318bf" + integrity sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw== + dependencies: + psl "^1.1.33" + punycode "^2.1.1" + universalify "^0.2.0" + url-parse "^1.5.3" + +tslib@^2.1.0: + version "2.6.2" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" + integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== + +tty-browserify@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" + integrity sha512-JVa5ijo+j/sOoHGjw0sxw734b1LhBkQ3bvUGNdxnVXDCX81Yx7TFgnZygxrIIWn23hbfTaMYLwRmAxFyDuFmIw== + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA== + +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== + +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== + +type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +typed-array-buffer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz#18de3e7ed7974b0a729d3feecb94338d1472cd60" + integrity sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.1" + is-typed-array "^1.1.10" + +typed-array-byte-length@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz#d787a24a995711611fb2b87a4052799517b230d0" + integrity sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA== + dependencies: + call-bind "^1.0.2" + for-each "^0.3.3" + has-proto "^1.0.1" + is-typed-array "^1.1.10" + +typed-array-byte-offset@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz#cbbe89b51fdef9cd6aaf07ad4707340abbc4ea0b" + integrity sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + for-each "^0.3.3" + has-proto "^1.0.1" + is-typed-array "^1.1.10" + +typed-array-length@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.4.tgz#89d83785e5c4098bec72e08b319651f0eac9c1bb" + integrity sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng== + dependencies: + call-bind "^1.0.2" + for-each "^0.3.3" + is-typed-array "^1.1.9" + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== + +typescript@4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.0.2.tgz#7ea7c88777c723c681e33bf7988be5d008d05ac2" + integrity sha512-e4ERvRV2wb+rRZ/IQeb3jm2VxBsirQLpQhdxplZ2MEzGvDkkMmPglecnNDfSUBivMjP93vRbngYYDQqQ/78bcQ== + +uglify-js@^3.1.4: + version "3.17.4" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.4.tgz#61678cf5fa3f5b7eb789bb345df29afb8257c22c" + integrity sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g== + +uid-safe@^2.1.0, uid-safe@~2.1.5: + version "2.1.5" + resolved "https://registry.yarnpkg.com/uid-safe/-/uid-safe-2.1.5.tgz#2b3d5c7240e8fc2e58f8aa269e5ee49c0857bd3a" + integrity sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA== + dependencies: + random-bytes "~1.0.0" + +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" + +undici-types@~5.26.4: + version "5.26.5" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" + integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== + +union-value@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" + integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^2.0.1" + +unique-filename@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" + integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== + dependencies: + unique-slug "^2.0.0" + +unique-slug@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c" + integrity sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w== + dependencies: + imurmurhash "^0.1.4" + +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@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.2.0.tgz#6451760566fa857534745ab1dde952d1b1761be0" + integrity sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg== + +universalify@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d" + integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== + +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ== + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +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== + +upath@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" + integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg== + +url-parse@^1.5.3: + version "1.5.10" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1" + integrity sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ== + dependencies: + querystringify "^2.1.1" + requires-port "^1.0.0" + +url@^0.11.0: + version "0.11.3" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.3.tgz#6f495f4b935de40ce4a0a52faee8954244f3d3ad" + integrity sha512-6hxOLGfZASQK/cijlZnZJTq8OXAkt/3YGfQX45vvMYXpZoo8NdWZcY73K108Jf759lS1Bv/8wXnHDTSz17dSRw== + dependencies: + punycode "^1.4.1" + qs "^6.11.2" + +use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== + +util-deprecate@^1.0.1, 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== + +util@^0.10.4: + version "0.10.4" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.4.tgz#3aa0125bfe668a4672de58857d3ace27ecb76901" + integrity sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A== + dependencies: + inherits "2.0.3" + +util@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/util/-/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61" + integrity sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ== + dependencies: + inherits "2.0.3" + +utils-flatten@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/utils-flatten/-/utils-flatten-1.0.0.tgz#01f30d3193be464c40b31755e6740d0db0cef243" + integrity sha512-s21PUgUZ+XPvH8Wi8aj2FEqzZWeNEdemP7LB4u8u5wTDRO4xB+7czAYd3FY2O2rnu89U//khR0Ce8ka3//6M0w== + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== + +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== + +valid-url@~1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/valid-url/-/valid-url-1.0.9.tgz#1c14479b40f1397a75782f115e4086447433a200" + integrity sha512-QQDsV8OnSf5Uc30CKSwG9lnhMPe6exHtTXLRYX8uMwKENy640pU+2BgBL0LRbDh/eYRahNCS7aewCx0wf3NYVA== + +validator@^13.6.0: + version "13.11.0" + resolved "https://registry.yarnpkg.com/validator/-/validator-13.11.0.tgz#23ab3fd59290c61248364eabf4067f04955fbb1b" + integrity sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ== + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw== + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +vm-browserify@^1.0.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" + integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== + +walk@2.3.15: + version "2.3.15" + resolved "https://registry.yarnpkg.com/walk/-/walk-2.3.15.tgz#1b4611e959d656426bc521e2da5db3acecae2424" + integrity sha512-4eRTBZljBfIISK1Vnt69Gvr2w/wc3U6Vtrw7qiN5iqYJPH7LElcYh/iU4XWhdCy2dZqv1ToMyYlybDylfG/5Vg== + dependencies: + foreachasync "^3.0.0" + +watchpack-chokidar2@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz#38500072ee6ece66f3769936950ea1771be1c957" + integrity sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww== + dependencies: + chokidar "^2.1.8" + +watchpack@^1.7.4: + version "1.7.5" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.7.5.tgz#1267e6c55e0b9b5be44c2023aed5437a2c26c453" + integrity sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ== + dependencies: + graceful-fs "^4.1.2" + neo-async "^2.5.0" + optionalDependencies: + chokidar "^3.4.1" + watchpack-chokidar2 "^2.0.1" + +webpack-sources@^1.4.0, webpack-sources@^1.4.1: + version "1.4.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" + integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== + dependencies: + source-list-map "^2.0.0" + source-map "~0.6.1" + +"webpack@npm:@amoo-miki/webpack@4.46.0-rc.2": + version "4.46.0-rc.2" + resolved "https://registry.yarnpkg.com/@amoo-miki/webpack/-/webpack-4.46.0-rc.2.tgz#36824597c14557a7bb0a8e13203e30275e7b02bd" + integrity sha512-Y/ZqxTHOoDF1kz3SR63Y9SZGTDUpZNNFrisTRHofWhP8QvNX3LMN+TCmEP56UfLaiLVKMcaiFjx8kFb2TgyBaQ== + dependencies: + "@node-rs/xxhash" "^1.3.0" + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-module-context" "1.9.0" + "@webassemblyjs/wasm-edit" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + acorn "^6.4.1" + ajv "^6.10.2" + ajv-keywords "^3.4.1" + chrome-trace-event "^1.0.2" + enhanced-resolve "^4.5.0" + eslint-scope "^4.0.3" + json-parse-better-errors "^1.0.2" + loader-runner "^2.4.0" + loader-utils "^2.0.4" + memory-fs "^0.4.1" + micromatch "^3.1.10" + mkdirp "^0.5.3" + neo-async "^2.6.1" + node-libs-browser "^2.2.1" + schema-utils "^1.0.0" + tapable "^1.1.3" + terser-webpack-plugin "npm:@amoo-miki/terser-webpack-plugin@1.4.5-rc.2" + watchpack "^1.7.4" + webpack-sources "^1.4.1" + +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-module@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.1.tgz#776b1fe35d90aebe99e8ac15eb24093389a4a409" + integrity sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ== + +which-typed-array@^1.1.11, which-typed-array@^1.1.13: + version "1.1.13" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.13.tgz#870cd5be06ddb616f504e7b039c4c24898184d36" + integrity sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.4" + for-each "^0.3.3" + gopd "^1.0.1" + has-tostringtag "^1.0.0" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +wordwrap@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== + +worker-farm@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" + integrity sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw== + dependencies: + errno "~0.1.7" + +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" + 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== + +ws@>=8.13.0: + version "8.14.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.14.2.tgz#6c249a806eb2db7a20d26d51e7709eab7b2e6c7f" + integrity sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g== + +xml-crypto@^2.0.0, xml-crypto@^2.1.3: + version "2.1.5" + resolved "https://registry.yarnpkg.com/xml-crypto/-/xml-crypto-2.1.5.tgz#e201ee51dca18dd9ae158ac101b6e995c983dca8" + integrity sha512-xOSJmGFm+BTXmaPYk8pPV3duKo6hJuZ5niN4uMzoNcTlwYs0jAu/N3qY+ud9MhE4N7eMRuC1ayC7Yhmb7MmAWg== + dependencies: + "@xmldom/xmldom" "^0.7.9" + xpath "0.0.32" + +xml-encryption@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/xml-encryption/-/xml-encryption-2.0.0.tgz#d4e1eb3ec1f2c5d2a2a0a6e23d199237e8b4bf83" + integrity sha512-4Av83DdvAgUQQMfi/w8G01aJshbEZP9ewjmZMpS9t3H+OCZBDvyK4GJPnHGfWiXlArnPbYvR58JB9qF2x9Ds+Q== + dependencies: + "@xmldom/xmldom" "^0.7.0" + escape-html "^1.0.3" + xpath "0.0.32" + +xml-formatter@^2.1.0: + version "2.6.1" + resolved "https://registry.yarnpkg.com/xml-formatter/-/xml-formatter-2.6.1.tgz#066ef3a100bd58ee3b943f0c503be63176d3d497" + integrity sha512-dOiGwoqm8y22QdTNI7A+N03tyVfBlQ0/oehAzxIZtwnFAHGeSlrfjF73YQvzSsa/Kt6+YZasKsrdu6OIpuBggw== + dependencies: + xml-parser-xo "^3.2.0" + +xml-name-validator@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-2.0.1.tgz#4d8b8f1eccd3419aa362061becef515e1e559635" + integrity sha512-jRKe/iQYMyVJpzPH+3HL97Lgu5HrCfii+qSo+TfjKHtOnvbnvdVfMYrn9Q34YV81M2e5sviJlI6Ko9y+nByzvA== + +xml-parser-xo@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/xml-parser-xo/-/xml-parser-xo-3.2.0.tgz#c633ab55cf1976d6b03ab4a6a85045093ac32b73" + integrity sha512-8LRU6cq+d7mVsoDaMhnkkt3CTtAs4153p49fRo+HIB3I1FD1o5CeXRjRH29sQevIfVJIcPjKSsPU/+Ujhq09Rg== + +xmldom@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.3.0.tgz#e625457f4300b5df9c2e1ecb776147ece47f3e5a" + integrity sha512-z9s6k3wxE+aZHgXYxSTpGDo7BYOUfJsIRyoZiX6HTjwpwfS2wpQBQKa2fD+ShLyPkqDYo5ud7KitmLZ2Cd6r0g== + +xpath@0.0.32: + version "0.0.32" + resolved "https://registry.yarnpkg.com/xpath/-/xpath-0.0.32.tgz#1b73d3351af736e17ec078d6da4b8175405c48af" + integrity sha512-rxMJhSIoiO8vXcWvSifKqhvV96GjiD5wYb8/QHdoRyQvraTpp4IEv944nhGausZZ3u7dhQXteZuZbaqfpB7uYw== + +xpath@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/xpath/-/xpath-0.0.5.tgz#454036f6ef0f3df5af5d4ba4a119fb75674b3e6c" + integrity sha512-Y1Oyy8lyIDwWpmKIWBF0RZrQOP1fzE12G0ekSB1yzKPtbAdCI5sBCqBU/CAZUkKk81OXuq9tul/5lyNS+22iKg== + +xtend@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-1.0.3.tgz#3f5d937353cced8e085399a563fdb22541c2960a" + integrity sha512-wv78b3q8kHDveC/C7Yq/UUrJXsAAM1t/j5m28h/ZlqYy0+eqByglhsWR88D2j3VImQzZlNIDsSbZ3QItwgWEGw== + +xtend@^4.0.0, xtend@~4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + +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@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + integrity sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A== + +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + +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@^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@^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@^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.7.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" + integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== + 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" + +yauzl@^2.10.0: + version "2.10.0" + resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" + integrity sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g== + dependencies: + buffer-crc32 "~0.2.3" + fd-slicer "~1.1.0" From 6dcd7d5b9c27c29a1297097b25fd3501ffd1bdb1 Mon Sep 17 00:00:00 2001 From: Derek Ho Date: Tue, 5 Dec 2023 12:46:56 -0500 Subject: [PATCH 20/32] Resolve debug, glob-parent to resolve CVE-2017-16137, CVE-2020-28469 (#1684) Signed-off-by: Derek Ho --- package.json | 4 +++- yarn.lock | 54 ++++------------------------------------------------ 2 files changed, 7 insertions(+), 51 deletions(-) diff --git a/package.json b/package.json index 06b726f60..9248e3e78 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,8 @@ "html-entities": "1.3.1" }, "resolutions": { - "selenium-webdriver": "4.10.0" + "selenium-webdriver": "4.10.0", + "glob-parent": "^5.1.2", + "debug": "^4.3.4" } } diff --git a/yarn.lock b/yarn.lock index e4dbcd2ee..95c23fe91 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1412,34 +1412,13 @@ dayjs@^1.10.4: resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.10.tgz#68acea85317a6e164457d6d6947564029a6a16a0" integrity sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ== -debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.9: - 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.1.0, debug@^3.2.7: - 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" - -debug@^4.1.1, debug@^4.3.4: +debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.9, debug@^3.1.0, debug@^3.2.7, debug@^4.1.1, debug@^4.3.4, debug@~4.1.1: 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@~4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" - integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== - 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" @@ -2243,15 +2222,7 @@ glob-all@^3.2.1: glob "^7.2.3" yargs "^15.3.1" -glob-parent@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" - integrity sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA== - dependencies: - is-glob "^3.1.0" - path-dirname "^1.0.0" - -glob-parent@~5.1.2: +glob-parent@5.1.2, glob-parent@^3.1.0, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== @@ -2662,7 +2633,7 @@ is-extendable@^1.0.1: dependencies: is-plain-object "^2.0.4" -is-extglob@^2.1.0, is-extglob@^2.1.1: +is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== @@ -2672,13 +2643,6 @@ is-fullwidth-code-point@^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-glob@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" - integrity sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw== - dependencies: - is-extglob "^2.1.0" - is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: version "4.0.3" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" @@ -3300,17 +3264,12 @@ move-concurrently@^1.0.1: rimraf "^2.5.4" run-queue "^1.0.3" -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.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.1: +ms@2.1.3: version "2.1.3" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== @@ -3569,11 +3528,6 @@ path-browserify@0.0.1: resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a" integrity sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ== -path-dirname@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" - integrity sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q== - path-exists@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" From 6374198119fcb2b33343460a3d2fdfcb44794f30 Mon Sep 17 00:00:00 2001 From: Craig Perkins Date: Fri, 8 Dec 2023 13:27:59 -0500 Subject: [PATCH 21/32] Implement nextUrl for OpenID Authentication (#1563) Signed-off-by: Craig Perkins Co-authored-by: Darshit Chanpura <35282393+DarshitChanpura@users.noreply.github.com> --- .github/workflows/cypress-test-oidc-e2e.yml | 1 - common/index.ts | 3 +- public/apps/login/login-page.tsx | 6 +- .../__snapshots__/login-page.test.tsx.snap | 2 +- server/auth/types/openid/openid_auth.ts | 35 +++-- server/auth/types/openid/routes.ts | 134 +++++++++++++++++- server/session/security_cookie.ts | 6 +- test/cypress/e2e/oidc/oidc_auth_test.spec.js | 100 ++++++------- 8 files changed, 216 insertions(+), 71 deletions(-) diff --git a/.github/workflows/cypress-test-oidc-e2e.yml b/.github/workflows/cypress-test-oidc-e2e.yml index c673018b7..6ef90f4fd 100644 --- a/.github/workflows/cypress-test-oidc-e2e.yml +++ b/.github/workflows/cypress-test-oidc-e2e.yml @@ -48,7 +48,6 @@ jobs: echo "Unpacking Keycloak" tar -xzf keycloak-${{ env.KEYCLOAK_VERSION }}.tar.gz cd keycloak-${{ env.KEYCLOAK_VERSION }}/bin - chmod +x ./kc.sh echo "Generating checksum for the downloaded kc.sh script..." DOWNLOADED_CHECKSUM=$(sha256sum kc.sh | awk '{print $1}') echo "Downloaded kc.sh checksum: $DOWNLOADED_CHECKSUM" diff --git a/common/index.ts b/common/index.ts index c688731d6..9b038a581 100644 --- a/common/index.ts +++ b/common/index.ts @@ -30,9 +30,10 @@ export const CUSTOM_ERROR_PAGE_URI = '/app/' + APP_ID_CUSTOMERROR; export const API_AUTH_LOGIN = '/auth/login'; export const API_AUTH_LOGOUT = '/auth/logout'; export const OPENID_AUTH_LOGIN = '/auth/openid/login'; +export const OPENID_AUTH_LOGIN_WITH_FRAGMENT = '/auth/openid/captureUrlFragment'; export const SAML_AUTH_LOGIN = '/auth/saml/login'; -export const ANONYMOUS_AUTH_LOGIN = '/auth/anonymous'; export const SAML_AUTH_LOGIN_WITH_FRAGMENT = '/auth/saml/captureUrlFragment'; +export const ANONYMOUS_AUTH_LOGIN = '/auth/anonymous'; export const OPENID_AUTH_LOGOUT = '/auth/openid/logout'; export const SAML_AUTH_LOGOUT = '/auth/saml/logout'; diff --git a/public/apps/login/login-page.tsx b/public/apps/login/login-page.tsx index 22421e3a7..70d894781 100644 --- a/public/apps/login/login-page.tsx +++ b/public/apps/login/login-page.tsx @@ -32,7 +32,7 @@ import { validateCurrentPassword } from '../../utils/login-utils'; import { ANONYMOUS_AUTH_LOGIN, AuthType, - OPENID_AUTH_LOGIN, + OPENID_AUTH_LOGIN_WITH_FRAGMENT, SAML_AUTH_LOGIN_WITH_FRAGMENT, } from '../../../common'; @@ -228,7 +228,9 @@ export function LoginPage(props: LoginPageDeps) { } case AuthType.OPEN_ID: { const oidcConfig = props.config.ui[AuthType.OPEN_ID].login; - formBodyOp.push(renderLoginButton(AuthType.OPEN_ID, OPENID_AUTH_LOGIN, oidcConfig)); + const nextUrl = extractNextUrlFromWindowLocation(); + const oidcAuthLoginUrl = OPENID_AUTH_LOGIN_WITH_FRAGMENT + nextUrl; + formBodyOp.push(renderLoginButton(AuthType.OPEN_ID, oidcAuthLoginUrl, oidcConfig)); break; } case AuthType.SAML: { diff --git a/public/apps/login/test/__snapshots__/login-page.test.tsx.snap b/public/apps/login/test/__snapshots__/login-page.test.tsx.snap index c2dac62c1..b8a1e1182 100644 --- a/public/apps/login/test/__snapshots__/login-page.test.tsx.snap +++ b/public/apps/login/test/__snapshots__/login-page.test.tsx.snap @@ -121,7 +121,7 @@ exports[`Login page renders renders with config value for multiauth 1`] = ` aria-label="openid_login_button" className="test-btn-style" data-test-subj="submit" - href="/app/opensearch-dashboards/auth/openid/login" + href="/app/opensearch-dashboards/auth/openid/captureUrlFragment?nextUrl=%2F" iconType="http://localhost:5601/images/test.png" size="s" type="prime" diff --git a/server/auth/types/openid/openid_auth.ts b/server/auth/types/openid/openid_auth.ts index 747cb84eb..4d59ea632 100644 --- a/server/auth/types/openid/openid_auth.ts +++ b/server/auth/types/openid/openid_auth.ts @@ -25,13 +25,17 @@ import { LifecycleResponseFactory, AuthToolkit, IOpenSearchDashboardsResponse, + AuthResult, } from 'opensearch-dashboards/server'; import HTTP from 'http'; import HTTPS from 'https'; import { PeerCertificate } from 'tls'; import { Server, ServerStateCookieOptions } from '@hapi/hapi'; import { SecurityPluginConfigType } from '../../..'; -import { SecuritySessionCookie } from '../../../session/security_cookie'; +import { + SecuritySessionCookie, + clearOldVersionCookieValue, +} from '../../../session/security_cookie'; import { OpenIdAuthRoutes } from './routes'; import { AuthenticationType } from '../authentication_type'; import { callTokenEndpoint } from './helper'; @@ -124,6 +128,22 @@ export class OpenIdAuthentication extends AuthenticationType { } } + private generateNextUrl(request: OpenSearchDashboardsRequest): string { + const path = + this.coreSetup.http.basePath.serverBasePath + + (request.url.pathname || '/app/opensearch-dashboards'); + return escape(path); + } + + private redirectOIDCCapture = (request: OpenSearchDashboardsRequest, toolkit: AuthToolkit) => { + const nextUrl = this.generateNextUrl(request); + const clearOldVersionCookie = clearOldVersionCookieValue(this.config); + return toolkit.redirected({ + location: `${this.coreSetup.http.basePath.serverBasePath}/auth/openid/captureUrlFragment?nextUrl=${nextUrl}`, + 'set-cookie': clearOldVersionCookie, + }); + }; + private createWreckClient(): typeof wreck { if (this.config.openid?.root_ca) { this.wreckHttpsOption.ca = [fs.readFileSync(this.config.openid.root_ca)]; @@ -297,18 +317,9 @@ export class OpenIdAuthentication extends AuthenticationType { request: OpenSearchDashboardsRequest, response: LifecycleResponseFactory, toolkit: AuthToolkit - ): IOpenSearchDashboardsResponse { + ): IOpenSearchDashboardsResponse | AuthResult { if (this.isPageRequest(request)) { - // nextUrl is a key value pair - const nextUrl = composeNextUrlQueryParam( - request, - this.coreSetup.http.basePath.serverBasePath - ); - return response.redirected({ - headers: { - location: `${this.coreSetup.http.basePath.serverBasePath}${OPENID_AUTH_LOGIN}?${nextUrl}`, - }, - }); + return this.redirectOIDCCapture(request, toolkit); } else { return response.unauthorized(); } diff --git a/server/auth/types/openid/routes.ts b/server/auth/types/openid/routes.ts index 46c0d6c88..a9b84e75c 100644 --- a/server/auth/types/openid/routes.ts +++ b/server/auth/types/openid/routes.ts @@ -100,6 +100,7 @@ export class OpenIdAuthRoutes { validate: validateNextUrl, }) ), + redirectHash: schema.maybe(schema.boolean()), state: schema.maybe(schema.string()), refresh: schema.maybe(schema.string()), }, @@ -135,6 +136,7 @@ export class OpenIdAuthRoutes { oidc: { state: nonce, nextUrl: getNextUrl(this.config, this.core, request), + redirectHash: request.query.redirectHash === 'true', }, authType: AuthType.OPEN_ID, }; @@ -164,6 +166,7 @@ export class OpenIdAuthRoutes { const nextUrl: string = cookie.oidc.nextUrl; const clientId = this.config.openid?.client_id; const clientSecret = this.config.openid?.client_secret; + const redirectHash: boolean = cookie.oidc?.redirectHash || false; const query: any = { grant_type: AUTH_GRANT_TYPE, code: request.query.code, @@ -211,11 +214,21 @@ export class OpenIdAuthRoutes { ); this.sessionStorageFactory.asScoped(request).set(sessionStorage); - return response.redirected({ - headers: { - location: nextUrl, - }, - }); + if (redirectHash) { + return response.redirected({ + headers: { + location: `${ + this.core.http.basePath.serverBasePath + }/auth/openid/redirectUrlFragment?nextUrl=${escape(nextUrl)}`, + }, + }); + } else { + return response.redirected({ + headers: { + location: nextUrl, + }, + }); + } } catch (error: any) { context.security_plugin.logger.error(`OpenId authentication failed: ${error}`); if (error.toString().toLowerCase().includes('authentication exception')) { @@ -271,5 +284,116 @@ export class OpenIdAuthRoutes { }); } ); + + // captureUrlFragment is the first route that will be invoked in the SP initiated login. + // This route will execute the captureUrlFragment.js script. + this.core.http.resources.register( + { + path: '/auth/openid/captureUrlFragment', + validate: { + query: schema.object({ + nextUrl: schema.maybe( + schema.string({ + validate: validateNextUrl, + }) + ), + }), + }, + options: { + authRequired: false, + }, + }, + async (context, request, response) => { + this.sessionStorageFactory.asScoped(request).clear(); + const serverBasePath = this.core.http.basePath.serverBasePath; + return response.renderHtml({ + body: ` + + OSD OIDC Capture + + + `, + }); + } + ); + + // This script will store the URL Hash in browser's local storage. + this.core.http.resources.register( + { + path: '/auth/openid/captureUrlFragment.js', + validate: false, + options: { + authRequired: false, + }, + }, + async (context, request, response) => { + this.sessionStorageFactory.asScoped(request).clear(); + return response.renderJs({ + body: `let oidcHash=window.location.hash.toString(); + let redirectHash = false; + if (oidcHash !== "") { + window.localStorage.removeItem('oidcHash'); + window.localStorage.setItem('oidcHash', oidcHash); + redirectHash = true; + } + let params = new URLSearchParams(window.location.search); + let nextUrl = params.get("nextUrl"); + finalUrl = "login?nextUrl=" + encodeURIComponent(nextUrl); + finalUrl += "&redirectHash=" + encodeURIComponent(redirectHash); + window.location.replace(finalUrl); + `, + }); + } + ); + + // Once the User is authenticated the browser will be redirected to '/auth/openid/redirectUrlFragment' + // route, which will execute the redirectUrlFragment.js. + this.core.http.resources.register( + { + path: '/auth/openid/redirectUrlFragment', + validate: { + query: schema.object({ + nextUrl: schema.any(), + }), + }, + options: { + authRequired: true, + }, + }, + async (context, request, response) => { + const serverBasePath = this.core.http.basePath.serverBasePath; + return response.renderHtml({ + body: ` + + OSD OpenID Success + + + `, + }); + } + ); + + // This script will pop the Hash from local storage if it exists. + // And forward the browser to the next url. + this.core.http.resources.register( + { + path: '/auth/openid/redirectUrlFragment.js', + validate: false, + options: { + authRequired: true, + }, + }, + async (context, request, response) => { + return response.renderJs({ + body: `let oidcHash=window.localStorage.getItem('oidcHash'); + window.localStorage.removeItem('oidcHash'); + let params = new URLSearchParams(window.location.search); + let nextUrl = params.get("nextUrl"); + finalUrl = nextUrl + oidcHash; + window.location.replace(finalUrl); + `, + }); + } + ); } } diff --git a/server/session/security_cookie.ts b/server/session/security_cookie.ts index 50b880d9b..c0365e7e1 100644 --- a/server/session/security_cookie.ts +++ b/server/session/security_cookie.ts @@ -30,7 +30,11 @@ export interface SecuritySessionCookie { tenant?: any; // for oidc auth workflow - oidc?: any; + oidc?: { + state?: string; + nextUrl?: string; + redirectHash?: boolean; + }; // for Saml auth workflow saml?: { diff --git a/test/cypress/e2e/oidc/oidc_auth_test.spec.js b/test/cypress/e2e/oidc/oidc_auth_test.spec.js index b4c5c80d2..08a7e8ae1 100644 --- a/test/cypress/e2e/oidc/oidc_auth_test.spec.js +++ b/test/cypress/e2e/oidc/oidc_auth_test.spec.js @@ -18,22 +18,22 @@ * SPDX-License-Identifier: Apache-2.0 */ -const login = 'admin'; -const password = 'admin'; - describe('Log in via OIDC', () => { afterEach(() => { - cy.origin('http://localhost:5601', () => { - cy.clearCookies(); - cy.clearLocalStorage(); - }); + cy.clearCookies(); + cy.clearLocalStorage(); }); const kcLogin = () => { - cy.get('#kc-page-title').should('be.visible'); - cy.get('input[id=username]').should('be.visible').type(login); - cy.get('input[id=password]').should('be.visible').type(password); - cy.get('#kc-login').click(); + cy.origin('http://127.0.0.1:8080', () => { + const login = 'admin'; + const password = 'admin'; + + cy.get('#kc-page-title').should('be.visible'); + cy.get('input[id=username]').should('be.visible').type(login); + cy.get('input[id=password]').should('be.visible').type(password); + cy.get('#kc-login').click(); + }); }; it('Login to app/opensearch_dashboards_overview#/ when OIDC is enabled', () => { @@ -43,14 +43,12 @@ describe('Log in via OIDC', () => { kcLogin(); - cy.origin('http://localhost:5601', () => { - localStorage.setItem('opendistro::security::tenant::saved', '""'); - localStorage.setItem('home:newThemeModal:show', 'false'); + localStorage.setItem('opendistro::security::tenant::saved', '""'); + localStorage.setItem('home:newThemeModal:show', 'false'); - cy.get('#osdOverviewPageHeader__title').should('be.visible'); + cy.get('#osdOverviewPageHeader__title').should('be.visible'); - cy.getCookie('security_authentication').should('exist'); - }); + cy.getCookie('security_authentication').should('exist'); }); it('Login to app/dev_tools#/console when OIDC is enabled', () => { @@ -60,33 +58,37 @@ describe('Log in via OIDC', () => { kcLogin(); - cy.origin('http://localhost:5601', () => { - localStorage.setItem('opendistro::security::tenant::saved', '""'); - localStorage.setItem('home:newThemeModal:show', 'false'); + localStorage.setItem('opendistro::security::tenant::saved', '""'); + localStorage.setItem('home:newThemeModal:show', 'false'); - cy.visit('http://localhost:5601/app/dev_tools#/console'); + cy.visit('http://localhost:5601/app/dev_tools#/console'); - cy.get('a').contains('Dev Tools').should('be.visible'); + cy.get('a').contains('Dev Tools').should('be.visible'); - cy.getCookie('security_authentication').should('exist'); - }); + cy.getCookie('security_authentication').should('exist'); }); it('Login to Dashboard with Hash', () => { - cy.visit( - `http://localhost:5601/app/dashboards#/view/7adfa750-4c81-11e8-b3d7-01146121b73d?_g=(filters:!(),refreshInterval:(pause:!f,value:900000),time:(from:now-24h,to:now))&_a=(description:'Analyze%20mock%20flight%20data%20for%20OpenSearch-Air,%20Logstash%20Airways,%20OpenSearch%20Dashboards%20Airlines%20and%20BeatsWest',filters:!(),fullScreenMode:!f,options:(hidePanelTitles:!f,useMargins:!t),query:(language:kuery,query:''),timeRestore:!t,title:'%5BFlights%5D%20Global%20Flight%20Dashboard',viewMode:view)` - ); + const urlWithHash = `http://localhost:5601/app/security-dashboards-plugin#/getstarted`; + + cy.visit(urlWithHash, { + failOnStatusCode: false, + }); kcLogin(); + cy.getCookie('security_authentication').should('exist'); + cy.getCookie('security_authentication_oidc1').should('exist'); - cy.origin('http://localhost:5601', () => { - localStorage.setItem('opendistro::security::tenant::saved', '""'); - localStorage.setItem('home:newThemeModal:show', 'false'); + cy.url().then((url) => { + cy.visit(url, { + failOnStatusCode: false, + }); + }); - cy.get('.euiHeader.euiHeader--default.euiHeader--fixed.primaryHeader').should('be.visible'); + localStorage.setItem('opendistro::security::tenant::saved', '""'); + localStorage.setItem('home:newThemeModal:show', 'false'); - cy.getCookie('security_authentication').should('exist'); - }); + cy.get('h1.euiTitle--large').contains('Get started'); }); it('Tenancy persisted after logout in OIDC', () => { @@ -96,30 +98,32 @@ describe('Log in via OIDC', () => { kcLogin(); - cy.origin('http://localhost:5601', () => { - localStorage.setItem('home:newThemeModal:show', 'false'); + cy.url().then((url) => { + cy.visit(url, { + failOnStatusCode: false, + }); + }); - cy.get('#private').should('be.enabled'); - cy.get('#private').click({ force: true }); + localStorage.setItem('home:newThemeModal:show', 'false'); - cy.get('button[data-test-subj="confirm"]').click(); + cy.get('#private').should('be.enabled'); + cy.get('#private').click({ force: true }); - cy.get('#osdOverviewPageHeader__title').should('be.visible'); + cy.get('button[data-test-subj="confirm"]').click(); - cy.get('button[id="user-icon-btn"]').click(); + cy.get('#osdOverviewPageHeader__title').should('be.visible'); - cy.get('button[data-test-subj^="log-out-"]').click(); - }); + cy.get('button[id="user-icon-btn"]').click(); + + cy.get('button[data-test-subj^="log-out-"]').click(); kcLogin(); - cy.origin('http://localhost:5601', () => { - cy.get('#user-icon-btn').should('be.visible'); - cy.get('#user-icon-btn').click(); + cy.get('#user-icon-btn').should('be.visible'); + cy.get('#user-icon-btn').click(); - cy.get('#osdOverviewPageHeader__title').should('be.visible'); + cy.get('#osdOverviewPageHeader__title').should('be.visible'); - cy.get('#tenantName').should('have.text', 'Private'); - }); + cy.get('#tenantName').should('have.text', 'Private'); }); }); From a88942988684964457082c33965d6a115603e6ac Mon Sep 17 00:00:00 2001 From: Derek Ho Date: Thu, 14 Dec 2023 12:37:04 -0500 Subject: [PATCH 22/32] Update instances of admin:admin in documentation and fix file location (#1696) Signed-off-by: Derek Ho --- .github/workflows/cypress-test-oidc-e2e.yml | 4 ++-- .github/workflows/cypress-test-saml-e2e.yml | 4 ++-- DEVELOPER_GUIDE.md | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/cypress-test-oidc-e2e.yml b/.github/workflows/cypress-test-oidc-e2e.yml index 6ef90f4fd..1118d07d0 100644 --- a/.github/workflows/cypress-test-oidc-e2e.yml +++ b/.github/workflows/cypress-test-oidc-e2e.yml @@ -158,10 +158,10 @@ jobs: cat config.yml # TODO: REMOVE THIS ONCE ADMIN JAVA TOOL SUPPORT IT - - name: Write password to initialAdminPassword location + - name: Write password to opensearch_initial_admin_password.txt if: ${{ runner.os == 'Linux'}} run: - echo admin >> ./opensearch-${{ env.OPENSEARCH_VERSION }}-SNAPSHOT/config/initialAdminPassword.txt + echo admin >> ./opensearch-${{ env.OPENSEARCH_VERSION }}-SNAPSHOT/config/opensearch_initial_admin_password.txt shell: bash # Run any configuration scripts diff --git a/.github/workflows/cypress-test-saml-e2e.yml b/.github/workflows/cypress-test-saml-e2e.yml index 7a329a9cc..a8f051500 100644 --- a/.github/workflows/cypress-test-saml-e2e.yml +++ b/.github/workflows/cypress-test-saml-e2e.yml @@ -58,10 +58,10 @@ jobs: shell: bash # TODO: REMOVE THIS ONCE ADMIN JAVA TOOL SUPPORT IT - - name: Write password to initialAdminPassword location + - name: Write password to opensearch_initial_admin_password.txt if: ${{ runner.os == 'Linux'}} run: - echo admin >> ./opensearch-${{ env.OPENSEARCH_VERSION }}-SNAPSHOT/config/initialAdminPassword.txt + echo admin >> ./opensearch-${{ env.OPENSEARCH_VERSION }}-SNAPSHOT/config/opensearch_initial_admin_password.txt shell: bash # Install the security plugin diff --git a/DEVELOPER_GUIDE.md b/DEVELOPER_GUIDE.md index 6c479f4b4..972f96c2d 100644 --- a/DEVELOPER_GUIDE.md +++ b/DEVELOPER_GUIDE.md @@ -35,7 +35,7 @@ For the sake of this guide, let's assume the latest version on main for OpenSear Ensure that an OpenSearch cluster with the security plugin installed is running locally. If you followed the steps from [the developer guide of the Security Plugin](https://github.com/opensearch-project/security/blob/main/DEVELOPER_GUIDE.md), then you can verify this by running: ``` -curl -XGET https://admin:admin@localhost:9200/ --insecure +curl -XGET https://admin:@localhost:9200/ --insecure ``` ## Install OpenSearch-Dashboards with Security Dashboards Plugin From 9c3ba49bef481071a1180a7ce1f17ff3c5b216dc Mon Sep 17 00:00:00 2001 From: Derek Ho Date: Tue, 26 Dec 2023 15:31:31 -0500 Subject: [PATCH 23/32] Remove txt file option and pass in env variable (#1707) Signed-off-by: Derek Ho --- .github/workflows/cypress-test-oidc-e2e.yml | 9 ++------- .github/workflows/cypress-test-saml-e2e.yml | 9 ++------- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/.github/workflows/cypress-test-oidc-e2e.yml b/.github/workflows/cypress-test-oidc-e2e.yml index 1118d07d0..5fe91f4d5 100644 --- a/.github/workflows/cypress-test-oidc-e2e.yml +++ b/.github/workflows/cypress-test-oidc-e2e.yml @@ -21,6 +21,8 @@ jobs: matrix: os: [ ubuntu-latest ] runs-on: ${{ matrix.os }} + env: + OPENSEARCH_INITIAL_ADMIN_PASSWORD: admin steps: - name: Set up JDK @@ -157,13 +159,6 @@ jobs: echo "THIS IS THE SECURITY CONFIG FILE: " cat config.yml - # TODO: REMOVE THIS ONCE ADMIN JAVA TOOL SUPPORT IT - - name: Write password to opensearch_initial_admin_password.txt - if: ${{ runner.os == 'Linux'}} - run: - echo admin >> ./opensearch-${{ env.OPENSEARCH_VERSION }}-SNAPSHOT/config/opensearch_initial_admin_password.txt - shell: bash - # Run any configuration scripts - name: Run Setup Script for Linux if: ${{ runner.os == 'Linux' }} diff --git a/.github/workflows/cypress-test-saml-e2e.yml b/.github/workflows/cypress-test-saml-e2e.yml index a8f051500..1029fa780 100644 --- a/.github/workflows/cypress-test-saml-e2e.yml +++ b/.github/workflows/cypress-test-saml-e2e.yml @@ -17,6 +17,8 @@ jobs: matrix: os: [ ubuntu-latest ] runs-on: ${{ matrix.os }} + env: + OPENSEARCH_INITIAL_ADMIN_PASSWORD: admin steps: - name: Set up JDK @@ -57,13 +59,6 @@ jobs: rm -f opensearch-*.tar.gz shell: bash - # TODO: REMOVE THIS ONCE ADMIN JAVA TOOL SUPPORT IT - - name: Write password to opensearch_initial_admin_password.txt - if: ${{ runner.os == 'Linux'}} - run: - echo admin >> ./opensearch-${{ env.OPENSEARCH_VERSION }}-SNAPSHOT/config/opensearch_initial_admin_password.txt - shell: bash - # Install the security plugin - name: Install Plugin into OpenSearch for Linux if: ${{ runner.os == 'Linux'}} From 09b2f59453b4b3d356ba7627d1e1af663fb075bd Mon Sep 17 00:00:00 2001 From: Yulong Ruan Date: Thu, 4 Jan 2024 00:23:18 +0800 Subject: [PATCH 24/32] fix Cannot find module when import ResourceType in server from public folder (#1705) * fix Cannot find module Signed-off-by: Yulong Ruan * fix prettier error Signed-off-by: Yulong Ruan * fix failed tests Signed-off-by: Yulong Ruan --------- Signed-off-by: Yulong Ruan Co-authored-by: Craig Perkins --- common/index.ts | 12 ++++++++++++ public/apps/configuration/app-router.tsx | 3 ++- .../audit-logging/audit-logging-edit-settings.tsx | 2 +- .../panels/audit-logging/audit-logging.tsx | 2 +- .../test/audit-logging-edit-settings.test.tsx | 2 +- .../panels/audit-logging/test/audit-logging.test.tsx | 2 +- public/apps/configuration/panels/get-started.tsx | 11 +++-------- .../panels/internal-user-edit/internal-user-edit.tsx | 3 ++- .../panels/role-edit/cluster-permission-panel.tsx | 3 ++- .../panels/role-edit/index-permission-panel.tsx | 7 ++++--- .../configuration/panels/role-edit/role-edit.tsx | 3 ++- public/apps/configuration/panels/role-list.tsx | 3 ++- .../panels/role-mapping/role-edit-mapped-user.tsx | 3 ++- .../panels/role-mapping/users-panel.tsx | 3 ++- .../panels/role-view/cluster-permission-panel.tsx | 3 ++- .../panels/role-view/index-permission-panel.tsx | 2 +- .../configuration/panels/role-view/role-view.tsx | 2 +- .../configuration/panels/role-view/tenants-panel.tsx | 8 ++------ .../role-view/test/cluster-permission-panel.test.tsx | 3 ++- .../role-view/test/index-permission-panel.test.tsx | 3 ++- .../panels/role-view/test/role-view.test.tsx | 3 ++- .../panels/role-view/test/tenants-panel.test.tsx | 3 ++- .../configuration/panels/service-account-list.tsx | 3 ++- .../configuration/panels/tenant-list/manage_tab.tsx | 7 +++---- .../configuration/panels/test/get-started.test.tsx | 3 ++- .../configuration/panels/test/role-list.test.tsx | 3 ++- .../panels/test/service-account-list.test.tsx | 3 ++- .../configuration/panels/test/user-list.test.tsx | 3 ++- public/apps/configuration/panels/user-list.tsx | 3 ++- public/apps/configuration/types.ts | 12 ------------ .../configuration/utils/internal-user-list-utils.tsx | 3 ++- public/apps/configuration/utils/url-builder.tsx | 3 ++- server/routes/index.ts | 2 +- 33 files changed, 71 insertions(+), 60 deletions(-) diff --git a/common/index.ts b/common/index.ts index 9b038a581..b5e6a475d 100644 --- a/common/index.ts +++ b/common/index.ts @@ -64,6 +64,18 @@ export enum AuthType { ANONYMOUS = 'anonymous', } +export enum ResourceType { + roles = 'roles', + users = 'users', + serviceAccounts = 'serviceAccounts', + permissions = 'permissions', + tenants = 'tenants', + tenantsManageTab = 'tenantsManageTab', + tenantsConfigureTab = 'tenantsConfigureTab', + auth = 'auth', + auditLogging = 'auditLogging', +} + /** * A valid resource name should not containing percent sign (%) as they raise url injection issue. * And also should not be empty. diff --git a/public/apps/configuration/app-router.tsx b/public/apps/configuration/app-router.tsx index a10cec08e..2e4ce7ca3 100644 --- a/public/apps/configuration/app-router.tsx +++ b/public/apps/configuration/app-router.tsx @@ -36,7 +36,8 @@ import { RoleView } from './panels/role-view/role-view'; import { TenantList } from './panels/tenant-list/tenant-list'; import { UserList } from './panels/user-list'; import { ServiceAccountList } from './panels/service-account-list'; -import { Action, ResourceType, RouteItem, SubAction } from './types'; +import { Action, RouteItem, SubAction } from './types'; +import { ResourceType } from '../../../common'; import { buildHashUrl, buildUrl } from './utils/url-builder'; import { CrossPageToast } from './cross-page-toast'; diff --git a/public/apps/configuration/panels/audit-logging/audit-logging-edit-settings.tsx b/public/apps/configuration/panels/audit-logging/audit-logging-edit-settings.tsx index 972442978..de5d0086f 100644 --- a/public/apps/configuration/panels/audit-logging/audit-logging-edit-settings.tsx +++ b/public/apps/configuration/panels/audit-logging/audit-logging-edit-settings.tsx @@ -31,7 +31,7 @@ import { SETTING_GROUPS, SettingMapItem } from './constants'; import { EditSettingGroup } from './edit-setting-group'; import { AuditLoggingSettings } from './types'; import { buildHashUrl, buildUrl } from '../../utils/url-builder'; -import { ResourceType } from '../../types'; +import { ResourceType } from '../../../../../common'; import { getAuditLogging, updateAuditLogging } from '../../utils/audit-logging-utils'; import { useToastState } from '../../utils/toast-utils'; import { setCrossPageToast } from '../../utils/storage-utils'; diff --git a/public/apps/configuration/panels/audit-logging/audit-logging.tsx b/public/apps/configuration/panels/audit-logging/audit-logging.tsx index e920c32e0..5ca10c84c 100644 --- a/public/apps/configuration/panels/audit-logging/audit-logging.tsx +++ b/public/apps/configuration/panels/audit-logging/audit-logging.tsx @@ -31,7 +31,7 @@ import { import React from 'react'; import { FormattedMessage } from '@osd/i18n/react'; import { AppDependencies } from '../../../types'; -import { ResourceType } from '../../types'; +import { ResourceType } from '../../../../../common'; import { getAuditLogging, updateAuditLogging } from '../../utils/audit-logging-utils'; import { displayBoolean, ExternalLink } from '../../utils/display-utils'; import { buildHashUrl } from '../../utils/url-builder'; diff --git a/public/apps/configuration/panels/audit-logging/test/audit-logging-edit-settings.test.tsx b/public/apps/configuration/panels/audit-logging/test/audit-logging-edit-settings.test.tsx index 038b0c5c8..a7b52d428 100644 --- a/public/apps/configuration/panels/audit-logging/test/audit-logging-edit-settings.test.tsx +++ b/public/apps/configuration/panels/audit-logging/test/audit-logging-edit-settings.test.tsx @@ -18,7 +18,7 @@ import { AuditLoggingEditSettings } from '../audit-logging-edit-settings'; import React from 'react'; import { ComplianceSettings, GeneralSettings } from '../types'; import { buildHashUrl } from '../../../utils/url-builder'; -import { ResourceType } from '../../../types'; +import { ResourceType } from '../../../../../../common'; jest.mock('../../../utils/audit-logging-utils'); diff --git a/public/apps/configuration/panels/audit-logging/test/audit-logging.test.tsx b/public/apps/configuration/panels/audit-logging/test/audit-logging.test.tsx index 35e6d0273..2bc5d4881 100644 --- a/public/apps/configuration/panels/audit-logging/test/audit-logging.test.tsx +++ b/public/apps/configuration/panels/audit-logging/test/audit-logging.test.tsx @@ -18,7 +18,7 @@ import { AuditLogging, renderComplianceSettings, renderGeneralSettings } from '. import React from 'react'; import { EuiSwitch } from '@elastic/eui'; import { buildHashUrl } from '../../../utils/url-builder'; -import { ResourceType } from '../../../types'; +import { ResourceType } from '../../../../../../common'; import { SUB_URL_FOR_COMPLIANCE_SETTINGS_EDIT, SUB_URL_FOR_GENERAL_SETTINGS_EDIT, diff --git a/public/apps/configuration/panels/get-started.tsx b/public/apps/configuration/panels/get-started.tsx index b2c562e35..dcf4fed41 100644 --- a/public/apps/configuration/panels/get-started.tsx +++ b/public/apps/configuration/panels/get-started.tsx @@ -27,17 +27,12 @@ import { } from '@elastic/eui'; import React from 'react'; import { FormattedMessage } from '@osd/i18n/react'; -import { flow } from 'lodash'; -import { HashRouter as Router, Route } from 'react-router-dom'; import { AppDependencies } from '../../types'; -import { buildHashUrl, buildUrl } from '../utils/url-builder'; -import { Action, ResourceType, RouteItem } from '../types'; +import { buildHashUrl } from '../utils/url-builder'; +import { Action } from '../types'; +import { ResourceType } from '../../../../common'; import { API_ENDPOINT_CACHE, DocLinks } from '../constants'; import { ExternalLink, ExternalLinkButton } from '../utils/display-utils'; -import { TenantList } from './tenant-list/tenant-list'; -import { getBreadcrumbs } from '../app-router'; - -import { CrossPageToast } from '../cross-page-toast'; const addBackendStep = { title: 'Add backends', diff --git a/public/apps/configuration/panels/internal-user-edit/internal-user-edit.tsx b/public/apps/configuration/panels/internal-user-edit/internal-user-edit.tsx index f93ef0407..1237ef9f3 100644 --- a/public/apps/configuration/panels/internal-user-edit/internal-user-edit.tsx +++ b/public/apps/configuration/panels/internal-user-edit/internal-user-edit.tsx @@ -26,7 +26,8 @@ import { } from '@elastic/eui'; import React, { useState } from 'react'; import { BreadcrumbsPageDependencies } from '../../../types'; -import { InternalUserUpdate, ResourceType } from '../../types'; +import { InternalUserUpdate } from '../../types'; +import { ResourceType } from '../../../../../common'; import { getUserDetail, updateUser } from '../../utils/internal-user-detail-utils'; import { PanelWithHeader } from '../../utils/panel-with-header'; import { PasswordEditPanel } from '../../utils/password-edit-panel'; diff --git a/public/apps/configuration/panels/role-edit/cluster-permission-panel.tsx b/public/apps/configuration/panels/role-edit/cluster-permission-panel.tsx index e80d0d0e1..3ac52f6d3 100644 --- a/public/apps/configuration/panels/role-edit/cluster-permission-panel.tsx +++ b/public/apps/configuration/panels/role-edit/cluster-permission-panel.tsx @@ -15,7 +15,8 @@ import React, { Dispatch, SetStateAction } from 'react'; import { EuiForm, EuiFlexGroup, EuiFlexItem, EuiComboBox } from '@elastic/eui'; -import { ComboBoxOptions, ResourceType } from '../../types'; +import { ComboBoxOptions } from '../../types'; +import { ResourceType } from '../../../../../common'; import { PanelWithHeader } from '../../utils/panel-with-header'; import { FormRow } from '../../utils/form-row'; import { LIMIT_WIDTH_INPUT_CLASS } from '../../constants'; diff --git a/public/apps/configuration/panels/role-edit/index-permission-panel.tsx b/public/apps/configuration/panels/role-edit/index-permission-panel.tsx index 75e2856e4..e52cb9128 100644 --- a/public/apps/configuration/panels/role-edit/index-permission-panel.tsx +++ b/public/apps/configuration/panels/role-edit/index-permission-panel.tsx @@ -25,7 +25,8 @@ import { } from '@elastic/eui'; import React, { Dispatch, Fragment, SetStateAction } from 'react'; import { isEmpty } from 'lodash'; -import { RoleIndexPermission, ResourceType } from '../../types'; +import { RoleIndexPermission } from '../../types'; +import { ResourceType } from '../../../../../common'; import { appendElementToArray, removeElementFromArray, @@ -141,9 +142,9 @@ export function IndexPermissionRow(props: { return ( diff --git a/public/apps/configuration/panels/role-edit/role-edit.tsx b/public/apps/configuration/panels/role-edit/role-edit.tsx index e5b3c832a..c237eaefd 100644 --- a/public/apps/configuration/panels/role-edit/role-edit.tsx +++ b/public/apps/configuration/panels/role-edit/role-edit.tsx @@ -46,7 +46,8 @@ import { } from './tenant-panel'; import { RoleIndexPermissionStateClass, RoleTenantPermissionStateClass } from './types'; import { buildHashUrl, buildUrl } from '../../utils/url-builder'; -import { ComboBoxOptions, ResourceType, Action, ActionGroupItem } from '../../types'; +import { ComboBoxOptions, Action, ActionGroupItem } from '../../types'; +import { ResourceType } from '../../../../../common'; import { useToastState, createUnknownErrorToast, diff --git a/public/apps/configuration/panels/role-list.tsx b/public/apps/configuration/panels/role-list.tsx index 1fb27a228..c9ecab34b 100644 --- a/public/apps/configuration/panels/role-list.tsx +++ b/public/apps/configuration/panels/role-list.tsx @@ -41,7 +41,8 @@ import { fetchRoleMapping, buildSearchFilterOptions, } from '../utils/role-list-utils'; -import { ResourceType, Action } from '../types'; +import { Action } from '../types'; +import { ResourceType } from '../../../../common'; import { buildHashUrl } from '../utils/url-builder'; import { ExternalLink, diff --git a/public/apps/configuration/panels/role-mapping/role-edit-mapped-user.tsx b/public/apps/configuration/panels/role-mapping/role-edit-mapped-user.tsx index 9b2a859da..44909bef5 100644 --- a/public/apps/configuration/panels/role-mapping/role-edit-mapped-user.tsx +++ b/public/apps/configuration/panels/role-mapping/role-edit-mapped-user.tsx @@ -35,7 +35,8 @@ import { ExternalIdentityStateClass } from './types'; import { ComboBoxOptions } from '../../types'; import { stringToComboBoxOption, comboBoxOptionToString } from '../../utils/combo-box-utils'; import { buildHashUrl, buildUrl } from '../../utils/url-builder'; -import { ResourceType, RoleMappingDetail, SubAction, Action } from '../../types'; +import { RoleMappingDetail, SubAction, Action } from '../../types'; +import { ResourceType } from '../../../../../common'; import { fetchUserNameList } from '../../utils/internal-user-list-utils'; import { updateRoleMapping, getRoleMappingData } from '../../utils/role-mapping-utils'; import { createErrorToast, createUnknownErrorToast, useToastState } from '../../utils/toast-utils'; diff --git a/public/apps/configuration/panels/role-mapping/users-panel.tsx b/public/apps/configuration/panels/role-mapping/users-panel.tsx index 39cec7538..6c65a152b 100644 --- a/public/apps/configuration/panels/role-mapping/users-panel.tsx +++ b/public/apps/configuration/panels/role-mapping/users-panel.tsx @@ -19,7 +19,8 @@ import { ComboBoxOptions } from '../../types'; import { PanelWithHeader } from '../../utils/panel-with-header'; import { FormRow } from '../../utils/form-row'; import { buildHashUrl } from '../../utils/url-builder'; -import { ResourceType, Action } from '../../types'; +import { Action } from '../../types'; +import { ResourceType } from '../../../../../common'; import { ExternalLinkButton } from '../../utils/display-utils'; import { DocLinks } from '../../constants'; import { appendOptionToComboBoxHandler } from '../../utils/combo-box-utils'; diff --git a/public/apps/configuration/panels/role-view/cluster-permission-panel.tsx b/public/apps/configuration/panels/role-view/cluster-permission-panel.tsx index 3d4a02df5..659f98c13 100644 --- a/public/apps/configuration/panels/role-view/cluster-permission-panel.tsx +++ b/public/apps/configuration/panels/role-view/cluster-permission-panel.tsx @@ -17,7 +17,8 @@ import React from 'react'; import { EuiEmptyPrompt, EuiButton } from '@elastic/eui'; import { PanelWithHeader } from '../../utils/panel-with-header'; import { PermissionTree } from '../permission-tree'; -import { ActionGroupItem, DataObject, ResourceType, Action } from '../../types'; +import { ActionGroupItem, DataObject, Action } from '../../types'; +import { ResourceType } from '../../../../../common'; import { buildHashUrl } from '../../utils/url-builder'; import { loadingSpinner } from '../../utils/loading-spinner-utils'; import { DocLinks } from '../../constants'; diff --git a/public/apps/configuration/panels/role-view/index-permission-panel.tsx b/public/apps/configuration/panels/role-view/index-permission-panel.tsx index b04583522..8c622afd3 100644 --- a/public/apps/configuration/panels/role-view/index-permission-panel.tsx +++ b/public/apps/configuration/panels/role-view/index-permission-panel.tsx @@ -30,9 +30,9 @@ import { ActionGroupItem, ExpandedRowMapInterface, RoleIndexPermissionView, - ResourceType, Action, } from '../../types'; +import { ResourceType } from '../../../../../common'; import { truncatedListView, displayArray, tableItemsUIProps } from '../../utils/display-utils'; import { PermissionTree } from '../permission-tree'; import { getFieldLevelSecurityMethod } from '../../utils/index-permission-utils'; diff --git a/public/apps/configuration/panels/role-view/role-view.tsx b/public/apps/configuration/panels/role-view/role-view.tsx index 04e5d1f99..723d546da 100644 --- a/public/apps/configuration/panels/role-view/role-view.tsx +++ b/public/apps/configuration/panels/role-view/role-view.tsx @@ -39,7 +39,6 @@ import { difference } from 'lodash'; import { BreadcrumbsPageDependencies } from '../../../types'; import { buildHashUrl, buildUrl } from '../../utils/url-builder'; import { - ResourceType, Action, SubAction, RoleMappingDetail, @@ -48,6 +47,7 @@ import { RoleIndexPermissionView, RoleTenantPermissionView, } from '../../types'; +import { ResourceType } from '../../../../../common'; import { getRoleMappingData, MappedUsersListing, diff --git a/public/apps/configuration/panels/role-view/tenants-panel.tsx b/public/apps/configuration/panels/role-view/tenants-panel.tsx index 667b34f45..45d19bb2b 100644 --- a/public/apps/configuration/panels/role-view/tenants-panel.tsx +++ b/public/apps/configuration/panels/role-view/tenants-panel.tsx @@ -26,12 +26,8 @@ import { import { CoreStart } from 'opensearch-dashboards/public'; import { getCurrentUser } from '../../../../utils/auth-info-utils'; import { PanelWithHeader } from '../../utils/panel-with-header'; -import { - RoleTenantPermissionView, - RoleTenantPermissionDetail, - ResourceType, - Action, -} from '../../types'; +import { RoleTenantPermissionView, RoleTenantPermissionDetail, Action } from '../../types'; +import { ResourceType } from '../../../../../common'; import { truncatedListView, tableItemsUIProps } from '../../utils/display-utils'; import { fetchTenants, diff --git a/public/apps/configuration/panels/role-view/test/cluster-permission-panel.test.tsx b/public/apps/configuration/panels/role-view/test/cluster-permission-panel.test.tsx index 5891ac502..8e7d5be0c 100644 --- a/public/apps/configuration/panels/role-view/test/cluster-permission-panel.test.tsx +++ b/public/apps/configuration/panels/role-view/test/cluster-permission-panel.test.tsx @@ -18,7 +18,8 @@ import { shallow } from 'enzyme'; import { ClusterPermissionPanel } from '../cluster-permission-panel'; import { EuiButton, EuiEmptyPrompt, EuiLoadingSpinner } from '@elastic/eui'; import { PermissionTree } from '../../permission-tree'; -import { Action, ResourceType } from '../../../types'; +import { Action } from '../../../types'; +import { ResourceType } from '../../../../../../common'; import { buildHashUrl } from '../../../utils/url-builder'; describe('Role view - cluster permission panel', () => { diff --git a/public/apps/configuration/panels/role-view/test/index-permission-panel.test.tsx b/public/apps/configuration/panels/role-view/test/index-permission-panel.test.tsx index 4c2f25555..dc9632eb2 100644 --- a/public/apps/configuration/panels/role-view/test/index-permission-panel.test.tsx +++ b/public/apps/configuration/panels/role-view/test/index-permission-panel.test.tsx @@ -15,7 +15,8 @@ import React from 'react'; import { shallow, mount } from 'enzyme'; -import { Action, ResourceType, RoleIndexPermissionView } from '../../../types'; +import { Action, RoleIndexPermissionView } from '../../../types'; +import { ResourceType } from '../../../../../../common'; import { renderFieldLevelSecurity, renderRowExpanstionArrow, diff --git a/public/apps/configuration/panels/role-view/test/role-view.test.tsx b/public/apps/configuration/panels/role-view/test/role-view.test.tsx index d793172ca..424154348 100644 --- a/public/apps/configuration/panels/role-view/test/role-view.test.tsx +++ b/public/apps/configuration/panels/role-view/test/role-view.test.tsx @@ -30,7 +30,8 @@ import { getRoleDetail } from '../../../utils/role-detail-utils'; import { transformRoleIndexPermissions } from '../../../utils/index-permission-utils'; import { useDeleteConfirmState } from '../../../utils/delete-confirm-modal-utils'; import { requestDeleteRoles } from '../../../utils/role-list-utils'; -import { Action, ResourceType, SubAction } from '../../../types'; +import { Action, SubAction } from '../../../types'; +import { ResourceType } from '../../../../../../common'; import { buildHashUrl } from '../../../utils/url-builder'; import { createUnknownErrorToast } from '../../../utils/toast-utils'; diff --git a/public/apps/configuration/panels/role-view/test/tenants-panel.test.tsx b/public/apps/configuration/panels/role-view/test/tenants-panel.test.tsx index 75cd9452e..5f5bb933d 100644 --- a/public/apps/configuration/panels/role-view/test/tenants-panel.test.tsx +++ b/public/apps/configuration/panels/role-view/test/tenants-panel.test.tsx @@ -18,7 +18,8 @@ import { mount, shallow } from 'enzyme'; import { TenantsPanel } from '../tenants-panel'; import { EuiEmptyPrompt, EuiInMemoryTable, EuiTableFieldDataColumnType } from '@elastic/eui'; import { buildHashUrl } from '../../../utils/url-builder'; -import { Action, ResourceType, RoleTenantPermissionDetail } from '../../../types'; +import { Action, RoleTenantPermissionDetail } from '../../../types'; +import { ResourceType } from '../../../../../../common'; import { RoleViewTenantInvalidText } from '../../../constants'; jest.mock('../../../utils/tenant-utils'); diff --git a/public/apps/configuration/panels/service-account-list.tsx b/public/apps/configuration/panels/service-account-list.tsx index 61c21a9e5..9feebba4a 100644 --- a/public/apps/configuration/panels/service-account-list.tsx +++ b/public/apps/configuration/panels/service-account-list.tsx @@ -34,7 +34,8 @@ import React, { useState } from 'react'; import { getAuthInfo } from '../../../utils/auth-info-utils'; import { AppDependencies } from '../../types'; import { API_ENDPOINT_SERVICEACCOUNTS, DocLinks } from '../constants'; -import { Action, ResourceType } from '../types'; +import { Action } from '../types'; +import { ResourceType } from '../../../../common'; import { EMPTY_FIELD_VALUE } from '../ui-constants'; import { useContextMenuState } from '../utils/context-menu'; import { ExternalLink, tableItemsUIProps, truncatedListView } from '../utils/display-utils'; diff --git a/public/apps/configuration/panels/tenant-list/manage_tab.tsx b/public/apps/configuration/panels/tenant-list/manage_tab.tsx index 8f813f82b..b235bd3ba 100644 --- a/public/apps/configuration/panels/tenant-list/manage_tab.tsx +++ b/public/apps/configuration/panels/tenant-list/manage_tab.tsx @@ -39,10 +39,10 @@ import React, { ReactNode, useState, useCallback } from 'react'; import { difference } from 'lodash'; import { HashRouter as Router, Route } from 'react-router-dom'; import { flow } from 'lodash'; -import { TenancyConfigSettings } from '../tenancy-config/types'; import { getCurrentUser } from '../../../../utils/auth-info-utils'; import { AppDependencies } from '../../../types'; -import { Action, ResourceType, Tenant } from '../../types'; +import { Action, Tenant } from '../../types'; +import { ResourceType } from '../../../../../common'; import { ExternalLink, renderCustomization, tableItemsUIProps } from '../../utils/display-utils'; import { fetchTenants, @@ -481,8 +481,7 @@ export function ManageTab(props: AppDependencies) { return ( <> {/*{tenancyDisabledWarning}*/} - - + diff --git a/public/apps/configuration/panels/test/get-started.test.tsx b/public/apps/configuration/panels/test/get-started.test.tsx index a3eb65bf1..e51af78f0 100644 --- a/public/apps/configuration/panels/test/get-started.test.tsx +++ b/public/apps/configuration/panels/test/get-started.test.tsx @@ -16,7 +16,8 @@ import { shallow } from 'enzyme'; import React from 'react'; import { EuiSteps } from '@elastic/eui'; -import { Action, ResourceType } from '../../types'; +import { Action } from '../../types'; +import { ResourceType } from '../../../../../common'; import { buildHashUrl } from '../../utils/url-builder'; import { GetStarted } from '../get-started'; diff --git a/public/apps/configuration/panels/test/role-list.test.tsx b/public/apps/configuration/panels/test/role-list.test.tsx index 445cdac43..a70dac666 100644 --- a/public/apps/configuration/panels/test/role-list.test.tsx +++ b/public/apps/configuration/panels/test/role-list.test.tsx @@ -18,7 +18,8 @@ import { mount, shallow } from 'enzyme'; import React from 'react'; import { EuiInMemoryTable, EuiTableFieldDataColumnType } from '@elastic/eui'; import { buildHashUrl } from '../../utils/url-builder'; -import { Action, ResourceType } from '../../types'; +import { Action } from '../../types'; +import { ResourceType } from '../../../../../common'; import { RoleListing } from '../../utils/role-list-utils'; import { useDeleteConfirmState } from '../../utils/delete-confirm-modal-utils'; diff --git a/public/apps/configuration/panels/test/service-account-list.test.tsx b/public/apps/configuration/panels/test/service-account-list.test.tsx index 2ffe595e8..d5407aeae 100644 --- a/public/apps/configuration/panels/test/service-account-list.test.tsx +++ b/public/apps/configuration/panels/test/service-account-list.test.tsx @@ -32,7 +32,8 @@ jest.mock('../../utils/context-menu', () => ({ import { getAuthInfo } from '../../../../utils/auth-info-utils'; import { buildHashUrl } from '../../utils/url-builder'; -import { ResourceType, Action } from '../../types'; +import { Action } from '../../types'; +import { ResourceType } from '../../../../../common'; describe('User list', () => { describe('dictView', () => { diff --git a/public/apps/configuration/panels/test/user-list.test.tsx b/public/apps/configuration/panels/test/user-list.test.tsx index fd28e74cf..32455fa53 100644 --- a/public/apps/configuration/panels/test/user-list.test.tsx +++ b/public/apps/configuration/panels/test/user-list.test.tsx @@ -40,7 +40,8 @@ jest.mock('../../utils/context-menu', () => ({ import { getAuthInfo } from '../../../../utils/auth-info-utils'; import { buildHashUrl } from '../../utils/url-builder'; -import { ResourceType, Action } from '../../types'; +import { Action } from '../../types'; +import { ResourceType } from '../../../../../common'; describe('User list', () => { describe('dictView', () => { diff --git a/public/apps/configuration/panels/user-list.tsx b/public/apps/configuration/panels/user-list.tsx index eb369f7ad..b75f62283 100644 --- a/public/apps/configuration/panels/user-list.tsx +++ b/public/apps/configuration/panels/user-list.tsx @@ -35,7 +35,8 @@ import React, { useState } from 'react'; import { getAuthInfo } from '../../../utils/auth-info-utils'; import { AppDependencies } from '../../types'; import { API_ENDPOINT_INTERNALUSERS, DocLinks } from '../constants'; -import { Action, ResourceType } from '../types'; +import { Action } from '../types'; +import { ResourceType } from '../../../../common'; import { EMPTY_FIELD_VALUE } from '../ui-constants'; import { useContextMenuState } from '../utils/context-menu'; import { useDeleteConfirmState } from '../utils/delete-confirm-modal-utils'; diff --git a/public/apps/configuration/types.ts b/public/apps/configuration/types.ts index fd64e1095..967072d18 100644 --- a/public/apps/configuration/types.ts +++ b/public/apps/configuration/types.ts @@ -19,18 +19,6 @@ export type ComboBoxOptions = EuiComboBoxOptionOption[]; export type FieldLevelSecurityMethod = 'exclude' | 'include'; -export enum ResourceType { - roles = 'roles', - users = 'users', - serviceAccounts = 'serviceAccounts', - permissions = 'permissions', - tenants = 'tenants', - tenantsManageTab = 'tenantsManageTab', - tenantsConfigureTab = 'tenantsConfigureTab', - auth = 'auth', - auditLogging = 'auditLogging', -} - export enum Action { view = 'view', create = 'create', diff --git a/public/apps/configuration/utils/internal-user-list-utils.tsx b/public/apps/configuration/utils/internal-user-list-utils.tsx index 02042e928..19b0488c7 100644 --- a/public/apps/configuration/utils/internal-user-list-utils.tsx +++ b/public/apps/configuration/utils/internal-user-list-utils.tsx @@ -20,7 +20,8 @@ import { API_ENDPOINT_INTERNALUSERS, API_ENDPOINT_SERVICEACCOUNTS, } from '../constants'; -import { DataObject, InternalUser, ObjectsMessage, ResourceType } from '../types'; +import { DataObject, InternalUser, ObjectsMessage } from '../types'; +import { ResourceType } from '../../../../common'; import { httpDelete, httpGet } from './request-utils'; import { getResourceUrl } from './resource-utils'; diff --git a/public/apps/configuration/utils/url-builder.tsx b/public/apps/configuration/utils/url-builder.tsx index 5337f627d..e15aa7975 100644 --- a/public/apps/configuration/utils/url-builder.tsx +++ b/public/apps/configuration/utils/url-builder.tsx @@ -13,7 +13,8 @@ * permissions and limitations under the License. */ -import { ResourceType, Action } from '../types'; +import { Action } from '../types'; +import { ResourceType } from '../../../../common'; /** * Build hash based url, encode the resourceId part diff --git a/server/routes/index.ts b/server/routes/index.ts index ad3dfbd58..934c63da7 100644 --- a/server/routes/index.ts +++ b/server/routes/index.ts @@ -21,7 +21,7 @@ import { OpenSearchDashboardsResponseFactory, } from 'opensearch-dashboards/server'; import { API_PREFIX, CONFIGURATION_API_PREFIX, isValidResourceName } from '../../common'; -import { ResourceType } from '../../public/apps/configuration/types'; +import { ResourceType } from '../../common'; // TODO: consider to extract entity CRUD operations and put it into a client class export function defineRoutes(router: IRouter) { From ac38d9d058013e0d6a9893b40a31df644981b2ad Mon Sep 17 00:00:00 2001 From: Craig Perkins Date: Thu, 4 Jan 2024 09:56:16 -0500 Subject: [PATCH 25/32] Handle other permission group types (#1715) Signed-off-by: Craig Perkins --- .../configuration/panels/role-edit/role-edit.tsx | 8 ++++++-- .../role-edit/test/role-edit-filtering.test.tsx | 14 ++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/public/apps/configuration/panels/role-edit/role-edit.tsx b/public/apps/configuration/panels/role-edit/role-edit.tsx index c237eaefd..a3364fe0b 100644 --- a/public/apps/configuration/panels/role-edit/role-edit.tsx +++ b/public/apps/configuration/panels/role-edit/role-edit.tsx @@ -176,7 +176,9 @@ export function RoleEdit(props: RoleEditDeps) { { label: 'Other permission groups', options: actionGroups - .filter((actionGroup) => actionGroup[1].type === undefined) + .filter( + (actionGroup) => !['cluster', 'index', 'kibana'].includes(actionGroup[1].type || '') + ) .map((actionGroup) => actionGroup[0]) .map(stringToComboBoxOption), }, @@ -197,7 +199,9 @@ export function RoleEdit(props: RoleEditDeps) { { label: 'Other permission groups', options: actionGroups - .filter((actionGroup) => actionGroup[1].type === undefined) + .filter( + (actionGroup) => !['cluster', 'index', 'kibana'].includes(actionGroup[1].type || '') + ) .map((actionGroup) => actionGroup[0]) .map(stringToComboBoxOption), }, diff --git a/public/apps/configuration/panels/role-edit/test/role-edit-filtering.test.tsx b/public/apps/configuration/panels/role-edit/test/role-edit-filtering.test.tsx index 4f3a4f909..68a521ab6 100644 --- a/public/apps/configuration/panels/role-edit/test/role-edit-filtering.test.tsx +++ b/public/apps/configuration/panels/role-edit/test/role-edit-filtering.test.tsx @@ -74,6 +74,14 @@ describe('Role edit filtering', () => { description: 'Custom group', static: true, }, + unlimited: { + reserved: false, + hidden: false, + allowed_actions: ['*'], + type: 'all', + description: 'Unlimited group', + static: true, + }, }); it('basic cluster permission panel rendering', async () => { @@ -118,6 +126,9 @@ describe('Role edit filtering', () => { { label: 'custom', }, + { + label: 'unlimited', + }, ], }, { @@ -171,6 +182,9 @@ describe('Role edit filtering', () => { { label: 'custom', }, + { + label: 'unlimited', + }, ], }, { From 96a449f5bf6c25aede181da93b0bf93545d66f7f Mon Sep 17 00:00:00 2001 From: Darshit Chanpura <35282393+DarshitChanpura@users.noreply.github.com> Date: Thu, 4 Jan 2024 13:33:08 -0500 Subject: [PATCH 26/32] Update cypress E2E workflow to reflect changes to default admin password (#1714) Signed-off-by: Darshit Chanpura --- .github/workflows/cypress-test-oidc-e2e.yml | 5 ++--- .github/workflows/cypress-test-saml-e2e.yml | 7 +++---- cypress.config.js | 2 +- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/.github/workflows/cypress-test-oidc-e2e.yml b/.github/workflows/cypress-test-oidc-e2e.yml index 5fe91f4d5..e93744965 100644 --- a/.github/workflows/cypress-test-oidc-e2e.yml +++ b/.github/workflows/cypress-test-oidc-e2e.yml @@ -12,6 +12,7 @@ env: PLUGIN_NAME: opensearch-security # This is the SHA256 checksum of the known good kc.sh script for Keycloak version 21.0.1. KNOWN_CHECKSUM_OF_KEYCLOAK_SCRIPT: 'f825ea1a9ffa5ad91673737c06857ababbb69b6b8f09e0c637b4c998517f9608' + OPENSEARCH_INITIAL_ADMIN_PASSWORD: myStrongPassword123! jobs: tests: @@ -21,8 +22,6 @@ jobs: matrix: os: [ ubuntu-latest ] runs-on: ${{ matrix.os }} - env: - OPENSEARCH_INITIAL_ADMIN_PASSWORD: admin steps: - name: Set up JDK @@ -184,7 +183,7 @@ jobs: # Verify that the server is operational - name: Check OpenSearch Running on Linux if: ${{ runner.os != 'Windows'}} - run: curl https://localhost:9200/_cat/plugins -u 'admin:admin' -k -v + run: curl https://localhost:9200/_cat/plugins -u 'admin:${{ env.OPENSEARCH_INITIAL_ADMIN_PASSWORD }}' -k -v shell: bash - if: always() diff --git a/.github/workflows/cypress-test-saml-e2e.yml b/.github/workflows/cypress-test-saml-e2e.yml index 1029fa780..046b466e6 100644 --- a/.github/workflows/cypress-test-saml-e2e.yml +++ b/.github/workflows/cypress-test-saml-e2e.yml @@ -8,7 +8,8 @@ env: # avoid warnings like "tput: No value for $TERM and no -T specified" TERM: xterm PLUGIN_NAME: opensearch-security - + OPENSEARCH_INITIAL_ADMIN_PASSWORD: myStrongPassword123! + jobs: tests: name: Run Cypress E2E SAML tests @@ -17,8 +18,6 @@ jobs: matrix: os: [ ubuntu-latest ] runs-on: ${{ matrix.os }} - env: - OPENSEARCH_INITIAL_ADMIN_PASSWORD: admin steps: - name: Set up JDK @@ -140,7 +139,7 @@ jobs: # Verify that the server is operational - name: Check OpenSearch Running on Linux if: ${{ runner.os != 'Windows'}} - run: curl https://localhost:9200/_cat/plugins -u 'admin:admin' -k -v + run: curl https://localhost:9200/_cat/plugins -u 'admin:${{ env.OPENSEARCH_INITIAL_ADMIN_PASSWORD }}' -k -v shell: bash - if: always() diff --git a/cypress.config.js b/cypress.config.js index 56d619ab5..e5a86728b 100644 --- a/cypress.config.js +++ b/cypress.config.js @@ -30,6 +30,6 @@ module.exports = defineConfig({ env: { openSearchUrl: 'https://localhost:9200', adminUserName: 'admin', - adminPassword: 'admin', + adminPassword: 'myStrongPassword123!', }, }); From d64ee4863db869d8e154381bd695fa5759be7034 Mon Sep 17 00:00:00 2001 From: Darshit Chanpura <35282393+DarshitChanpura@users.noreply.github.com> Date: Thu, 4 Jan 2024 14:13:35 -0500 Subject: [PATCH 27/32] Adds system index permission as allowed action under static drop down list (#1695) Signed-off-by: Darshit Chanpura Co-authored-by: Stephen Crawford <65832608+scrawfor99@users.noreply.github.com> --- public/apps/configuration/constants.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/public/apps/configuration/constants.tsx b/public/apps/configuration/constants.tsx index 84d3fb75a..1649e5365 100644 --- a/public/apps/configuration/constants.tsx +++ b/public/apps/configuration/constants.tsx @@ -315,6 +315,7 @@ export const INDEX_PERMISSIONS: string[] = [ 'indices:monitor/shard_stores', 'indices:monitor/stats', 'indices:monitor/upgrade', + 'system:admin/system_index', ]; export function includeIndexPermissions(indexPermissionsToInclude: string[]) { From 7cad47c38478646cd96f0eb1623b77acd853b803 Mon Sep 17 00:00:00 2001 From: Jochen Kressin <126353411+jochen-kressin@users.noreply.github.com> Date: Thu, 4 Jan 2024 22:17:36 +0100 Subject: [PATCH 28/32] Cookie compression and splitting for JWT (#1651) Signed-off-by: Jochen Kressin Co-authored-by: Craig Perkins --- server/auth/types/jwt/jwt_auth.ts | 99 ++++++++++++++-- server/auth/types/jwt/jwt_helper.test.ts | 137 ++++++++++++++++++++++- server/auth/types/jwt/routes.ts | 23 +++- server/index.ts | 11 ++ test/jest_integration/jwt_auth.test.ts | 39 ++++++- 5 files changed, 293 insertions(+), 16 deletions(-) diff --git a/server/auth/types/jwt/jwt_auth.ts b/server/auth/types/jwt/jwt_auth.ts index 3b8ef365a..43f17708c 100644 --- a/server/auth/types/jwt/jwt_auth.ts +++ b/server/auth/types/jwt/jwt_auth.ts @@ -25,10 +25,21 @@ import { AuthToolkit, IOpenSearchDashboardsResponse, } from 'opensearch-dashboards/server'; +import { ServerStateCookieOptions } from '@hapi/hapi'; import { SecurityPluginConfigType } from '../../..'; import { SecuritySessionCookie } from '../../../session/security_cookie'; import { AuthenticationType } from '../authentication_type'; import { JwtAuthRoutes } from './routes'; +import { + ExtraAuthStorageOptions, + getExtraAuthStorageValue, + setExtraAuthStorage, +} from '../../../session/cookie_splitter'; + +export const JWT_DEFAULT_EXTRA_STORAGE_OPTIONS: ExtraAuthStorageOptions = { + cookiePrefix: 'security_authentication_jwt', + additionalCookies: 5, +}; export class JwtAuthentication extends AuthenticationType { public readonly type: string = 'jwt'; @@ -48,10 +59,47 @@ export class JwtAuthentication extends AuthenticationType { } public async init() { - const routes = new JwtAuthRoutes(this.router, this.sessionStorageFactory); + this.createExtraStorage(); + const routes = new JwtAuthRoutes(this.router, this.sessionStorageFactory, this.config); routes.setupRoutes(); } + createExtraStorage() { + // @ts-ignore + const hapiServer: Server = this.sessionStorageFactory.asScoped({}).server; + + const { cookiePrefix, additionalCookies } = this.getExtraAuthStorageOptions(); + const extraCookieSettings: ServerStateCookieOptions = { + isSecure: this.config.cookie.secure, + isSameSite: this.config.cookie.isSameSite, + password: this.config.cookie.password, + domain: this.config.cookie.domain, + path: this.coreSetup.http.basePath.serverBasePath || '/', + clearInvalid: false, + isHttpOnly: true, + ignoreErrors: true, + encoding: 'iron', // Same as hapi auth cookie + }; + + for (let i = 1; i <= additionalCookies; i++) { + hapiServer.states.add(cookiePrefix + i, extraCookieSettings); + } + } + + private getExtraAuthStorageOptions(): ExtraAuthStorageOptions { + const extraAuthStorageOptions: ExtraAuthStorageOptions = { + cookiePrefix: + this.config.jwt?.extra_storage.cookie_prefix || + JWT_DEFAULT_EXTRA_STORAGE_OPTIONS.cookiePrefix, + additionalCookies: + this.config.jwt?.extra_storage.additional_cookies || + JWT_DEFAULT_EXTRA_STORAGE_OPTIONS.additionalCookies, + logger: this.logger, + }; + + return extraAuthStorageOptions; + } + private getTokenFromUrlParam(request: OpenSearchDashboardsRequest): string | undefined { const urlParamName = this.config.jwt?.url_param; if (urlParamName) { @@ -77,6 +125,7 @@ export class JwtAuthentication extends AuthenticationType { if (request.headers[this.authHeaderName]) { return true; } + const urlParamName = this.config.jwt?.url_param; if (urlParamName && request.url.searchParams.get(urlParamName)) { return true; @@ -100,22 +149,29 @@ export class JwtAuthentication extends AuthenticationType { request: OpenSearchDashboardsRequest, authInfo: any ): SecuritySessionCookie { + setExtraAuthStorage( + request, + this.getBearerToken(request) || '', + this.getExtraAuthStorageOptions() + ); return { username: authInfo.user_name, credentials: { - authHeaderValue: this.getBearerToken(request), + authHeaderValueExtra: true, }, authType: this.type, expiryTime: Date.now() + this.config.session.ttl, }; } - async isValidCookie(cookie: SecuritySessionCookie): Promise { + async isValidCookie( + cookie: SecuritySessionCookie, + request: OpenSearchDashboardsRequest + ): Promise { + const hasAuthHeaderValue = + cookie.credentials?.authHeaderValue || this.getExtraAuthStorageValue(request, cookie); return ( - cookie.authType === this.type && - cookie.username && - cookie.expiryTime && - cookie.credentials?.authHeaderValue + cookie.authType === this.type && cookie.username && cookie.expiryTime && hasAuthHeaderValue ); } @@ -127,8 +183,35 @@ export class JwtAuthentication extends AuthenticationType { return response.unauthorized(); } - buildAuthHeaderFromCookie(cookie: SecuritySessionCookie): any { + getExtraAuthStorageValue(request: OpenSearchDashboardsRequest, cookie: SecuritySessionCookie) { + let extraValue = ''; + if (!cookie.credentials?.authHeaderValueExtra) { + return extraValue; + } + + try { + extraValue = getExtraAuthStorageValue(request, this.getExtraAuthStorageOptions()); + } catch (error) { + this.logger.info(error); + } + + return extraValue; + } + + buildAuthHeaderFromCookie( + cookie: SecuritySessionCookie, + request: OpenSearchDashboardsRequest + ): any { const header: any = {}; + if (cookie.credentials.authHeaderValueExtra) { + try { + const extraAuthStorageValue = this.getExtraAuthStorageValue(request, cookie); + header.authorization = extraAuthStorageValue; + return header; + } catch (error) { + this.logger.error(error); + } + } const authHeaderValue = cookie.credentials?.authHeaderValue; if (authHeaderValue) { header[this.authHeaderName] = authHeaderValue; diff --git a/server/auth/types/jwt/jwt_helper.test.ts b/server/auth/types/jwt/jwt_helper.test.ts index c8fca618d..73dd0e0ab 100644 --- a/server/auth/types/jwt/jwt_helper.test.ts +++ b/server/auth/types/jwt/jwt_helper.test.ts @@ -14,18 +14,58 @@ */ import { getAuthenticationHandler } from '../../auth_handler_factory'; +import { JWT_DEFAULT_EXTRA_STORAGE_OPTIONS } from './jwt_auth'; +import { + CoreSetup, + ILegacyClusterClient, + IRouter, + Logger, + OpenSearchDashboardsRequest, + SessionStorageFactory, +} from '../../../../../../src/core/server'; +import { SecuritySessionCookie } from '../../../session/security_cookie'; +import { SecurityPluginConfigType } from '../../../index'; +import { httpServerMock } from '../../../../../../src/core/server/http/http_server.mocks'; +import { deflateValue } from '../../../utils/compression'; describe('test jwt auth library', () => { - const router: IRouter = { post: (body) => {} }; - let core: CoreSetup; + const router: Partial = { post: (body) => {} }; + const core = { + http: { + basePath: { + serverBasePath: '/', + }, + }, + } as CoreSetup; let esClient: ILegacyClusterClient; - let sessionStorageFactory: SessionStorageFactory; + const sessionStorageFactory: SessionStorageFactory = { + asScoped: jest.fn().mockImplementation(() => { + return { + server: { + states: { + add: jest.fn(), + }, + }, + }; + }), + }; let logger: Logger; + const cookieConfig: Partial = { + cookie: { + secure: false, + name: 'test_cookie_name', + password: 'secret', + ttl: 60 * 60 * 1000, + domain: null, + isSameSite: false, + }, + }; + function getTestJWTAuthenticationHandlerWithConfig(config: SecurityPluginConfigType) { return getAuthenticationHandler( 'jwt', - router, + router as IRouter, config, core, esClient, @@ -36,9 +76,14 @@ describe('test jwt auth library', () => { test('test getTokenFromUrlParam', async () => { const config = { + ...cookieConfig, jwt: { header: 'Authorization', url_param: 'authorization', + extra_storage: { + cookie_prefix: JWT_DEFAULT_EXTRA_STORAGE_OPTIONS.cookiePrefix, + additional_cookies: JWT_DEFAULT_EXTRA_STORAGE_OPTIONS.additionalCookies, + }, }, }; const auth = await getTestJWTAuthenticationHandlerWithConfig(config); @@ -55,9 +100,14 @@ describe('test jwt auth library', () => { test('test getTokenFromUrlParam incorrect url_param', async () => { const config = { + ...cookieConfig, jwt: { header: 'Authorization', url_param: 'urlParamName', + extra_storage: { + cookie_prefix: JWT_DEFAULT_EXTRA_STORAGE_OPTIONS.cookiePrefix, + additional_cookies: JWT_DEFAULT_EXTRA_STORAGE_OPTIONS.additionalCookies, + }, }, }; const auth = await getTestJWTAuthenticationHandlerWithConfig(config); @@ -71,4 +121,83 @@ describe('test jwt auth library', () => { const token = auth.getTokenFromUrlParam(request); expect(token).toEqual(expectedToken); }); + + test('make sure that cookies with authHeaderValue instead of split cookies are still valid', async () => { + const config = { + ...cookieConfig, + jwt: { + header: 'Authorization', + url_param: 'authorization', + extra_storage: { + cookie_prefix: JWT_DEFAULT_EXTRA_STORAGE_OPTIONS.cookiePrefix, + additional_cookies: JWT_DEFAULT_EXTRA_STORAGE_OPTIONS.additionalCookies, + }, + }, + } as SecurityPluginConfigType; + + const jwtAuthentication = await getTestJWTAuthenticationHandlerWithConfig(config); + + const mockRequest = httpServerMock.createRawRequest(); + const osRequest = OpenSearchDashboardsRequest.from(mockRequest); + + const cookie: SecuritySessionCookie = { + credentials: { + authHeaderValue: 'Bearer eyToken', + }, + }; + + const expectedHeaders = { + authorization: 'Bearer eyToken', + }; + + const headers = jwtAuthentication.buildAuthHeaderFromCookie(cookie, osRequest); + + expect(headers).toEqual(expectedHeaders); + }); + + test('get authHeaderValue from split cookies', async () => { + const config = { + ...cookieConfig, + jwt: { + header: 'Authorization', + url_param: 'authorization', + extra_storage: { + cookie_prefix: 'testcookie', + additional_cookies: 2, + }, + }, + } as SecurityPluginConfigType; + + const jwtAuthentication = await getTestJWTAuthenticationHandlerWithConfig(config); + + const testString = 'Bearer eyCombinedToken'; + const testStringBuffer: Buffer = deflateValue(testString); + const cookieValue = testStringBuffer.toString('base64'); + const cookiePrefix = config.jwt!.extra_storage.cookie_prefix; + const splitValueAt = Math.ceil( + cookieValue.length / config.jwt!.extra_storage.additional_cookies + ); + const mockRequest = httpServerMock.createRawRequest({ + state: { + [cookiePrefix + '1']: cookieValue.substring(0, splitValueAt), + [cookiePrefix + '2']: cookieValue.substring(splitValueAt), + }, + }); + + const osRequest = OpenSearchDashboardsRequest.from(mockRequest); + + const cookie: SecuritySessionCookie = { + credentials: { + authHeaderValueExtra: true, + }, + }; + + const expectedHeaders = { + authorization: testString, + }; + + const headers = jwtAuthentication.buildAuthHeaderFromCookie(cookie, osRequest); + + expect(headers).toEqual(expectedHeaders); + }); }); diff --git a/server/auth/types/jwt/routes.ts b/server/auth/types/jwt/routes.ts index 27ee57c3c..14d2ce6bb 100644 --- a/server/auth/types/jwt/routes.ts +++ b/server/auth/types/jwt/routes.ts @@ -13,16 +13,34 @@ * permissions and limitations under the License. */ -import { IRouter, SessionStorageFactory } from 'opensearch-dashboards/server'; +import { IRouter, Logger, SessionStorageFactory } from 'opensearch-dashboards/server'; import { SecuritySessionCookie } from '../../../session/security_cookie'; import { API_AUTH_LOGOUT, API_PREFIX } from '../../../../common'; +import { clearSplitCookies, ExtraAuthStorageOptions } from '../../../session/cookie_splitter'; +import { JWT_DEFAULT_EXTRA_STORAGE_OPTIONS } from './jwt_auth'; +import { SecurityPluginConfigType } from '../../../index'; export class JwtAuthRoutes { constructor( private readonly router: IRouter, - private readonly sessionStorageFactory: SessionStorageFactory + private readonly sessionStorageFactory: SessionStorageFactory, + private readonly config: SecurityPluginConfigType ) {} + private getExtraAuthStorageOptions(logger?: Logger): ExtraAuthStorageOptions { + const extraAuthStorageOptions: ExtraAuthStorageOptions = { + cookiePrefix: + this.config.jwt?.extra_storage.cookie_prefix || + JWT_DEFAULT_EXTRA_STORAGE_OPTIONS.cookiePrefix, + additionalCookies: + this.config.jwt?.extra_storage.additional_cookies || + JWT_DEFAULT_EXTRA_STORAGE_OPTIONS.additionalCookies, + logger, + }; + + return extraAuthStorageOptions; + } + public setupRoutes() { this.router.post( { @@ -33,6 +51,7 @@ export class JwtAuthRoutes { }, }, async (context, request, response) => { + await clearSplitCookies(request, this.getExtraAuthStorageOptions()); this.sessionStorageFactory.asScoped(request).clear(); return response.ok(); } diff --git a/server/index.ts b/server/index.ts index 915da0315..68a20f533 100644 --- a/server/index.ts +++ b/server/index.ts @@ -17,6 +17,7 @@ import { schema, TypeOf } from '@osd/config-schema'; import { PluginInitializerContext, PluginConfigDescriptor } from '../../../src/core/server'; import { SecurityPlugin } from './plugin'; import { AuthType } from '../common'; +import { JWT_DEFAULT_EXTRA_STORAGE_OPTIONS } from './auth/types/jwt/jwt_auth'; const validateAuthType = (value: string[]) => { const supportedAuthTypes = [ @@ -233,6 +234,16 @@ export const configSchema = schema.object({ login_endpoint: schema.maybe(schema.string()), url_param: schema.string({ defaultValue: 'authorization' }), header: schema.string({ defaultValue: 'Authorization' }), + extra_storage: schema.object({ + cookie_prefix: schema.string({ + defaultValue: JWT_DEFAULT_EXTRA_STORAGE_OPTIONS.cookiePrefix, + minLength: 2, + }), + additional_cookies: schema.number({ + min: 1, + defaultValue: JWT_DEFAULT_EXTRA_STORAGE_OPTIONS.additionalCookies, + }), + }), }) ), ui: schema.object({ diff --git a/test/jest_integration/jwt_auth.test.ts b/test/jest_integration/jwt_auth.test.ts index 12c6d3ccc..41f9b0cc5 100644 --- a/test/jest_integration/jwt_auth.test.ts +++ b/test/jest_integration/jwt_auth.test.ts @@ -237,7 +237,7 @@ describe('start OpenSearch Dashboards server', () => { await driver.wait(until.elementsLocated(By.xpath(pageTitleXPath)), 10000); const cookie = await driver.manage().getCookies(); - expect(cookie.length).toEqual(1); + expect(cookie.length).toEqual(2); await driver.manage().deleteAllCookies(); await driver.quit(); }); @@ -263,7 +263,7 @@ describe('start OpenSearch Dashboards server', () => { ); const cookie = await driver.manage().getCookies(); - expect(cookie.length).toEqual(1); + expect(cookie.length).toEqual(2); await driver.manage().deleteAllCookies(); await driver.quit(); }); @@ -321,6 +321,41 @@ describe('start OpenSearch Dashboards server', () => { await driver.manage().deleteAllCookies(); await driver.quit(); }); + + it('Login to app/opensearch_dashboards_overview#/ when JWT is enabled and the token contains too many roles for one single cookie', async () => { + const roles = ['admin']; + // Generate "random" roles to add to the token. + // Compared to just using one role with a very long name, + // this should make it a bit harder for the cookie compression. + for (let i = 0; i < 500; i++) { + const dummyRole = Math.random().toString(20).substr(2, 10); + roles.push(dummyRole); + } + + const payload = { + sub: 'jwt_test', + roles: roles.join(','), + }; + + const key = new TextEncoder().encode(rawKey); + + const token = await new SignJWT(payload) // details to encode in the token + .setProtectedHeader({ alg: 'HS256' }) // algorithm + .setIssuedAt() + .sign(key); + const driver = getDriver(browser, options).build(); + await driver.get(`http://localhost:5601/app/opensearch_dashboards_overview?token=${token}`); + await driver.wait(until.elementsLocated(By.xpath(pageTitleXPath)), 10000); + + const cookie = await driver.manage().getCookies(); + // Testing the amount of cookies may be a bit fragile. + // The important thing here is that we know that + // we can handle a large payload and still be + // able to render the authenticated page + expect(cookie.length).toBeGreaterThan(2); + await driver.manage().deleteAllCookies(); + await driver.quit(); + }); }); function getDriver(browser: string, options: Options) { From 780b3aae00362af053806b83e74e81359208e8c5 Mon Sep 17 00:00:00 2001 From: Craig Perkins Date: Thu, 11 Jan 2024 13:19:04 -0500 Subject: [PATCH 29/32] Add indices:data/read/search/template/render to cluster permissions dropdown (#1725) Signed-off-by: Craig Perkins --- public/apps/configuration/constants.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/public/apps/configuration/constants.tsx b/public/apps/configuration/constants.tsx index 1649e5365..9df5f8285 100644 --- a/public/apps/configuration/constants.tsx +++ b/public/apps/configuration/constants.tsx @@ -240,6 +240,7 @@ export const CLUSTER_PERMISSIONS: string[] = [ 'indices:data/read/msearch/template', 'indices:data/read/mtv', 'indices:data/read/mtv*', + 'indices:data/read/search/template/render', 'indices:data/write/reindex', ]; From b5f713437624fcff69e2cdda3810b17246832425 Mon Sep 17 00:00:00 2001 From: Craig Perkins Date: Thu, 11 Jan 2024 16:11:49 -0500 Subject: [PATCH 30/32] Run `cypress-tests` and `cypress-tests-tenancy-disabled` on Chrome (#1728) Signed-off-by: Craig Perkins Co-authored-by: Darshit Chanpura <35282393+DarshitChanpura@users.noreply.github.com> --- .github/workflows/cypress-test-tenancy-disabled.yml | 8 ++++---- .github/workflows/cypress-test.yml | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/cypress-test-tenancy-disabled.yml b/.github/workflows/cypress-test-tenancy-disabled.yml index 3c6c084cf..862520418 100644 --- a/.github/workflows/cypress-test-tenancy-disabled.yml +++ b/.github/workflows/cypress-test-tenancy-disabled.yml @@ -12,12 +12,12 @@ env: PLUGIN_NAME: opensearch-security jobs: - tests: + cypress-tests-multitenancy-disabled: name: Run Cypress Tests Multitenancy Disabled strategy: fail-fast: false matrix: - os: [ ubuntu-latest , windows-latest ] + os: [ubuntu-latest] runs-on: ${{ matrix.os }} steps: @@ -50,7 +50,7 @@ jobs: opensearch-version: ${{ env.OPENSEARCH_VERSION }} plugin-name: ${{ env.PLUGIN_NAME }} setup-script-name: setup - admin-password: admin + admin-password: myStrongPassword123! - name: Run Dashboard with Security Dashboards Plugin uses: ./.github/actions/install-dashboards @@ -74,4 +74,4 @@ jobs: git clone https://github.com/opensearch-project/opensearch-dashboards-functional-test.git cd opensearch-dashboards-functional-test npm install cypress --save-dev - yarn cypress:run-with-security --browser firefox --spec "cypress/integration/plugins/security-dashboards-plugin/inaccessible_tenancy_features.js" + yarn cypress:run-with-security --browser chrome --spec "cypress/integration/plugins/security-dashboards-plugin/inaccessible_tenancy_features.js" diff --git a/.github/workflows/cypress-test.yml b/.github/workflows/cypress-test.yml index 745ef077d..5f73c999e 100644 --- a/.github/workflows/cypress-test.yml +++ b/.github/workflows/cypress-test.yml @@ -12,12 +12,12 @@ env: PLUGIN_NAME: opensearch-security jobs: - tests: + cypress-tests: name: Run Cypress tests strategy: fail-fast: false matrix: - os: [ ubuntu-latest , windows-latest ] + os: [ubuntu-latest] runs-on: ${{ matrix.os }} steps: @@ -50,7 +50,7 @@ jobs: opensearch-version: ${{ env.OPENSEARCH_VERSION }} plugin-name: ${{ env.PLUGIN_NAME }} setup-script-name: setup - admin-password: admin + admin-password: myStrongPassword123! - name: Run Dashboard with Security Dashboards Plugin uses: ./.github/actions/install-dashboards @@ -76,6 +76,6 @@ jobs: git clone https://github.com/opensearch-project/opensearch-dashboards-functional-test.git cd opensearch-dashboards-functional-test npm install cypress --save-dev - yarn cypress:run-with-security-and-aggregation-view --browser firefox --spec "cypress/integration/plugins/security-dashboards-plugin/aggregation_view.js" - yarn cypress:run-with-security --browser firefox --spec "cypress/integration/plugins/security-dashboards-plugin/multi_tenancy.js" - yarn cypress:run-with-security --browser firefox --spec "cypress/integration/plugins/security-dashboards-plugin/default_tenant.js" + yarn cypress:run-with-security-and-aggregation-view --browser chrome --spec "cypress/integration/plugins/security-dashboards-plugin/aggregation_view.js" + yarn cypress:run-with-security --browser chrome --spec "cypress/integration/plugins/security-dashboards-plugin/multi_tenancy.js" + yarn cypress:run-with-security --browser chrome --spec "cypress/integration/plugins/security-dashboards-plugin/default_tenant.js" From 9b88d92eb92f88e62a611aea0461d435c032d590 Mon Sep 17 00:00:00 2001 From: Derek Ho Date: Tue, 16 Jan 2024 16:17:08 -0500 Subject: [PATCH 31/32] Run Security dashboards plugin from binary (#1726) Signed-off-by: Derek Ho --- .../workflows/verify-binary-installation.yml | 139 ++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 .github/workflows/verify-binary-installation.yml diff --git a/.github/workflows/verify-binary-installation.yml b/.github/workflows/verify-binary-installation.yml new file mode 100644 index 000000000..04e9dc21c --- /dev/null +++ b/.github/workflows/verify-binary-installation.yml @@ -0,0 +1,139 @@ +name: 'Install Dashboards with Plugin via Binary' + +on: [push, pull_request] +env: + OPENSEARCH_VERSION: '3.0.0' + CI: 1 + # avoid warnings like "tput: No value for $TERM and no -T specified" + TERM: xterm + PLUGIN_NAME: opensearch-security + OPENSEARCH_INITIAL_ADMIN_PASSWORD: myStrongPassword123! + +jobs: + verify-binary-installation: + name: Run binary installation + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest] + # TODO: add windows support when OSD core is stable on windows + runs-on: ${{ matrix.os }} + steps: + - name: Checkout Branch + uses: actions/checkout@v3 + + - name: Set up JDK + uses: actions/setup-java@v1 + with: + java-version: 11 + + - name: Set env + run: | + opensearch_version=$(node -p "require('./package.json').opensearchDashboards.version") + plugin_version=$(node -p "require('./package.json').version") + echo "OPENSEARCH_VERSION=$opensearch_version" >> $GITHUB_ENV + echo "PLUGIN_VERSION=$plugin_version" >> $GITHUB_ENV + shell: bash + + - name: Download security plugin and create setup scripts + uses: ./.github/actions/download-plugin + with: + opensearch-version: ${{ env.OPENSEARCH_VERSION }} + plugin-name: ${{ env.PLUGIN_NAME }} + plugin-version: ${{ env.PLUGIN_VERSION }} + + - name: Run Opensearch with A Single Plugin + uses: opensearch-project/security/.github/actions/start-opensearch-with-one-plugin@main + with: + opensearch-version: ${{ env.OPENSEARCH_VERSION }} + plugin-name: ${{ env.PLUGIN_NAME }} + setup-script-name: setup + admin-password: ${{ env.OPENSEARCH_INITIAL_ADMIN_PASSWORD }} + + - uses: actions/checkout@v2 + with: + path: OpenSearch-Dashboards + repository: opensearch-project/OpenSearch-Dashboards + ref: 'main' + fetch-depth: 0 + filter: | + cypress + test + + - id: branch-switch-if-possible + continue-on-error: true # Defaults onto main if the branch switch doesn't work + if: ${{ steps.osd-version.outputs.osd-version }} + run: git checkout ${{ steps.osd-version.outputs.osd-version }} || git checkout ${{ steps.osd-version.outputs.osd-x-version }} + working-directory: ./OpenSearch-Dashboards + shell: bash + + - id: tool-versions + run: | + echo "node_version=$(cat .node-version)" >> $GITHUB_OUTPUT + echo "yarn_version=$(jq -r '.engines.yarn' package.json)" >> $GITHUB_OUTPUT + working-directory: OpenSearch-Dashboards + shell: bash + + - uses: actions/setup-node@v1 + with: + node-version: ${{ steps.tool-versions.outputs.node_version }} + registry-url: 'https://registry.npmjs.org' + + - name: Setup Opensearch Dashboards + run: | + npm uninstall -g yarn + echo "Installing yarn ${{ steps.tool-versions.outputs.yarn_version }}" + npm i -g yarn@${{ steps.tool-versions.outputs.yarn_version }} + yarn cache clean + yarn add sha.js + yarn osd bootstrap + scripts/use_node scripts/build + working-directory: OpenSearch-Dashboards + shell: bash + + - uses: actions/checkout@v2 + with: + path: OpenSearch-Dashboards/plugins/security-dashboards-plugin + + - name: Build Plugin Zip + run: | + yarn build + working-directory: OpenSearch-Dashboards/plugins/security-dashboards-plugin + shell: bash + + - name: Install plugin to OSD Linux + run: | + build/opensearch-dashboards-${{ env.OPENSEARCH_VERSION }}-SNAPSHOT-linux-x64/bin/opensearch-dashboards-plugin install file:$(pwd)/plugins/security-dashboards-plugin/build/security-dashboards-${{env.PLUGIN_VERSION}}.zip + working-directory: OpenSearch-Dashboards + shell: bash + + - name: Write security settings into OSD yml file + run: | + rm -rf ./config/opensearch_dashboards.yml + cat << 'EOT' > ./config/opensearch_dashboards.yml + server.host: "0.0.0.0" + opensearch.hosts: ["https://localhost:9200"] + opensearch.ssl.verificationMode: none + opensearch.username: "kibanaserver" + opensearch.password: "kibanaserver" + opensearch.requestHeadersWhitelist: [ authorization,securitytenant ] + opensearch_security.multitenancy.enabled: true + opensearch_security.multitenancy.tenants.preferred: ["Private", "Global"] + opensearch_security.readonly_mode.roles: ["kibana_read_only"] + + # Use this setting if you are running opensearch-dashboards without https + opensearch_security.cookie.secure: false + working-directory: OpenSearch-Dashboards/build/opensearch-dashboards-${{ env.OPENSEARCH_VERSION }}-SNAPSHOT-linux-x64 + + + - name: Start the binary + run: | + nohup ./bin/opensearch-dashboards & + working-directory: OpenSearch-Dashboards/build/opensearch-dashboards-${{ env.OPENSEARCH_VERSION }}-SNAPSHOT-linux-x64 + shell: bash + + - name: Health check + run: | + timeout 300 bash -c 'while [[ "$(curl -u admin:${{ env.OPENSEARCH_INITIAL_ADMIN_PASSWORD }} -k http://localhost:5601/api/status | jq -r '.status.overall.state')" != "green" ]]; do sleep 5; done' + shell: bash + From 3f81415d6c77bb275b3d3a84a8409cccdc30a7a1 Mon Sep 17 00:00:00 2001 From: Derek Ho Date: Wed, 17 Jan 2024 11:33:03 -0500 Subject: [PATCH 32/32] Forward port the change (#1739) Signed-off-by: Derek Ho --- .github/workflows/verify-binary-installation.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/verify-binary-installation.yml b/.github/workflows/verify-binary-installation.yml index 04e9dc21c..4acfda86f 100644 --- a/.github/workflows/verify-binary-installation.yml +++ b/.github/workflows/verify-binary-installation.yml @@ -60,6 +60,12 @@ jobs: cypress test + - id: osd-version + run: | + echo "::set-output name=osd-version::$(jq -r '.opensearchDashboards.version | split(".") | .[:2] | join(".")' package.json)" + echo "::set-output name=osd-x-version::$(jq -r '.opensearchDashboards.version | split(".") | .[0]' package.json).x" + shell: bash + - id: branch-switch-if-possible continue-on-error: true # Defaults onto main if the branch switch doesn't work if: ${{ steps.osd-version.outputs.osd-version }}