From 32719d38a2c4a8a9341898d3db4be0445d32ead3 Mon Sep 17 00:00:00 2001 From: dvonanderson Date: Mon, 27 Feb 2023 17:56:44 -0500 Subject: [PATCH 001/193] =?UTF-8?q?chore:=20=F0=9F=A4=96=20added=20session?= =?UTF-8?q?-recordings=20route?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Created new `session-recordings` and `sessions-recordings/index` route βœ… Closes: ICU-8215 --- addons/core/translations/resources/en-us.yaml | 3 +++ ui/admin/app/router.js | 1 + .../routes/scopes/scope/session-recordings.js | 3 +++ .../scopes/scope/session-recordings/index.js | 3 +++ .../scopes/scope/session-recordings.hbs | 2 ++ .../scopes/scope/session-recordings/index.hbs | 0 .../scopes/scope/session-recordings-test.js | 11 +++++++++++ .../scope/session-recordings/index-test.js | 16 ++++++++++++++++ 8 files changed, 39 insertions(+) create mode 100644 ui/admin/app/routes/scopes/scope/session-recordings.js create mode 100644 ui/admin/app/routes/scopes/scope/session-recordings/index.js create mode 100644 ui/admin/app/templates/scopes/scope/session-recordings.hbs create mode 100644 ui/admin/app/templates/scopes/scope/session-recordings/index.hbs create mode 100644 ui/admin/tests/unit/routes/scopes/scope/session-recordings-test.js create mode 100644 ui/admin/tests/unit/routes/scopes/scope/session-recordings/index-test.js diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml index 6d13011c0..7d9d2589c 100644 --- a/addons/core/translations/resources/en-us.yaml +++ b/addons/core/translations/resources/en-us.yaml @@ -208,6 +208,9 @@ org: new: New Org actions: delete: Delete Org +session-recordings: + title: Session Recording + title_plural: Session Recordings project: title: Project title_plural: Projects diff --git a/ui/admin/app/router.js b/ui/admin/app/router.js index f7f67698f..80d396bd6 100644 --- a/ui/admin/app/router.js +++ b/ui/admin/app/router.js @@ -132,6 +132,7 @@ Router.map(function () { this.route('new'); this.route('worker', { path: ':worker_id' }, function () {}); }); + this.route('session-recordings', function () {}); }); }); diff --git a/ui/admin/app/routes/scopes/scope/session-recordings.js b/ui/admin/app/routes/scopes/scope/session-recordings.js new file mode 100644 index 000000000..f45ef2bd4 --- /dev/null +++ b/ui/admin/app/routes/scopes/scope/session-recordings.js @@ -0,0 +1,3 @@ +import Route from '@ember/routing/route'; + +export default class ScopesScopeSessionRecordingsRoute extends Route {} diff --git a/ui/admin/app/routes/scopes/scope/session-recordings/index.js b/ui/admin/app/routes/scopes/scope/session-recordings/index.js new file mode 100644 index 000000000..4e136d667 --- /dev/null +++ b/ui/admin/app/routes/scopes/scope/session-recordings/index.js @@ -0,0 +1,3 @@ +import Route from '@ember/routing/route'; + +export default class ScopesScopeSessionRecordingsIndexRoute extends Route {} diff --git a/ui/admin/app/templates/scopes/scope/session-recordings.hbs b/ui/admin/app/templates/scopes/scope/session-recordings.hbs new file mode 100644 index 000000000..8a94562e7 --- /dev/null +++ b/ui/admin/app/templates/scopes/scope/session-recordings.hbs @@ -0,0 +1,2 @@ +{{page-title (t 'resources.session-recording.title_plural')}} +{{outlet}} \ No newline at end of file diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs new file mode 100644 index 000000000..e69de29bb diff --git a/ui/admin/tests/unit/routes/scopes/scope/session-recordings-test.js b/ui/admin/tests/unit/routes/scopes/scope/session-recordings-test.js new file mode 100644 index 000000000..83b111bb5 --- /dev/null +++ b/ui/admin/tests/unit/routes/scopes/scope/session-recordings-test.js @@ -0,0 +1,11 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'admin/tests/helpers'; + +module('Unit | Route | scopes/scope/session-recordings', function (hooks) { + setupTest(hooks); + + test('it exists', function (assert) { + let route = this.owner.lookup('route:scopes/scope/session-recordings'); + assert.ok(route); + }); +}); diff --git a/ui/admin/tests/unit/routes/scopes/scope/session-recordings/index-test.js b/ui/admin/tests/unit/routes/scopes/scope/session-recordings/index-test.js new file mode 100644 index 000000000..eed6a0983 --- /dev/null +++ b/ui/admin/tests/unit/routes/scopes/scope/session-recordings/index-test.js @@ -0,0 +1,16 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'admin/tests/helpers'; + +module( + 'Unit | Route | scopes/scope/session-recordings/index', + function (hooks) { + setupTest(hooks); + + test('it exists', function (assert) { + let route = this.owner.lookup( + 'route:scopes/scope/session-recordings/index' + ); + assert.ok(route); + }); + } +); From 18ecef4c0bfbc89c255447fe7682483748bdf1e5 Mon Sep 17 00:00:00 2001 From: Devon Anderson Date: Mon, 27 Feb 2023 19:05:19 -0500 Subject: [PATCH 002/193] Update en-us.yaml changed `session-recordings` to `session-recording` in resources.yaml --- addons/core/translations/resources/en-us.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml index 7d9d2589c..f2f9818fa 100644 --- a/addons/core/translations/resources/en-us.yaml +++ b/addons/core/translations/resources/en-us.yaml @@ -208,7 +208,7 @@ org: new: New Org actions: delete: Delete Org -session-recordings: +session-recording: title: Session Recording title_plural: Session Recordings project: From b0c3bd11f7c15f21de7aa820e5f74e8d838ad9e3 Mon Sep 17 00:00:00 2001 From: lisbet-alvarez <107949262+lisbet-alvarez@users.noreply.github.com> Date: Tue, 28 Feb 2023 08:09:08 -0800 Subject: [PATCH 003/193] ICU-8130 add session-recording feature flag (#78) * ICU-8130 add session-recording feature flag --- ui/admin/config/environment.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ui/admin/config/environment.js b/ui/admin/config/environment.js index 208f6bbbc..5d87bfc15 100644 --- a/ui/admin/config/environment.js +++ b/ui/admin/config/environment.js @@ -18,6 +18,7 @@ const featureEditions = { 'target-worker-filters-v2-hcp': false, 'target-network-address': true, 'credential-library-vault-ssh-certificate': false, + 'session-recording': false, }, }; featureEditions.enterprise = { @@ -156,6 +157,7 @@ module.exports = function (environment) { ENV.featureFlags['target-worker-filters-v2-hcp'] = true; ENV.featureFlags['target-network-address'] = true; ENV.featureFlags['credential-library-vault-ssh-certificate'] = true; + ENV.featureFlags['session-recording'] = true; } if (environment === 'test') { From 774377db76cc8a123efd0892936af14cf04f820d Mon Sep 17 00:00:00 2001 From: dvonanderson Date: Tue, 28 Feb 2023 11:18:50 -0500 Subject: [PATCH 004/193] =?UTF-8?q?chore:=20=F0=9F=A4=96=20create=20sessio?= =?UTF-8?q?n-recording=20route?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Create `session-recording` route with empty landing page. Added translations to `resources.yaml` file. βœ… Closes: ICU-8270 --- addons/core/translations/resources/en-us.yaml | 5 ++- ui/admin/app/router.js | 8 ++++- .../routes/scopes/scope/session-recordings.js | 36 ++++++++++++++++++- 3 files changed, 46 insertions(+), 3 deletions(-) diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml index f2f9818fa..8814160a6 100644 --- a/addons/core/translations/resources/en-us.yaml +++ b/addons/core/translations/resources/en-us.yaml @@ -208,9 +208,12 @@ org: new: New Org actions: delete: Delete Org -session-recording: +session-recordings: title: Session Recording title_plural: Session Recordings + recorded-sessions: + title: Recorded Session + title_plural: Recorded Sessions project: title: Project title_plural: Projects diff --git a/ui/admin/app/router.js b/ui/admin/app/router.js index 80d396bd6..52a5ca380 100644 --- a/ui/admin/app/router.js +++ b/ui/admin/app/router.js @@ -132,7 +132,13 @@ Router.map(function () { this.route('new'); this.route('worker', { path: ':worker_id' }, function () {}); }); - this.route('session-recordings', function () {}); + this.route('session-recordings', function () { + this.route( + 'session-recording', + { path: ':session_recording_id' }, + function () {} + ); + }); }); }); diff --git a/ui/admin/app/routes/scopes/scope/session-recordings.js b/ui/admin/app/routes/scopes/scope/session-recordings.js index f45ef2bd4..8713f2966 100644 --- a/ui/admin/app/routes/scopes/scope/session-recordings.js +++ b/ui/admin/app/routes/scopes/scope/session-recordings.js @@ -1,3 +1,37 @@ import Route from '@ember/routing/route'; +import { inject as service } from '@ember/service'; -export default class ScopesScopeSessionRecordingsRoute extends Route {} +export default class ScopesScopeSessionRecordingsRoute extends Route { + // =services + + @service store; + @service can; + @service session; + @service router; + + // =methods + + /** + * If arriving here unauthenticated, redirect to index for further processing. + */ + beforeModel() { + if (!this.session.isAuthenticated) this.router.transitionTo('index'); + } + + /** + * Load all session recordings. + * @return {SessionRecordingModel} + */ + model() { + // TODO: awaiting modeled data + // const scope = this.modelFor('scopes.scope'); + // const { id: scope_id } = scope; + // if (this.can.can('list session-recording', scope, { collection: 'session-recordings' })) { + // return this.store.query('session-recording', { scope_id }); + // } + + return 'i am session-recordings'; + } + + // =actions +} From 3d0477b95741c365ce6c1ab35ba3b3c63e98d4f8 Mon Sep 17 00:00:00 2001 From: dvonanderson Date: Tue, 28 Feb 2023 11:27:40 -0500 Subject: [PATCH 005/193] =?UTF-8?q?chore:=20=F0=9F=A4=96=20added=20all=20o?= =?UTF-8?q?f=20the=20uncommitted=20files?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Session-recording files --- .../session-recordings/session-recording.js | 6 ++++++ .../session-recording/index.js | 3 +++ .../session-recordings/session-recording.hbs | 3 +++ .../session-recording/index.hbs | 0 .../session-recordings/session-recording-test.js | 16 ++++++++++++++++ .../session-recording/index-test.js | 16 ++++++++++++++++ 6 files changed, 44 insertions(+) create mode 100644 ui/admin/app/routes/scopes/scope/session-recordings/session-recording.js create mode 100644 ui/admin/app/routes/scopes/scope/session-recordings/session-recording/index.js create mode 100644 ui/admin/app/templates/scopes/scope/session-recordings/session-recording.hbs create mode 100644 ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs create mode 100644 ui/admin/tests/unit/routes/scopes/scope/session-recordings/session-recording-test.js create mode 100644 ui/admin/tests/unit/routes/scopes/scope/session-recordings/session-recording/index-test.js diff --git a/ui/admin/app/routes/scopes/scope/session-recordings/session-recording.js b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording.js new file mode 100644 index 000000000..9224bab43 --- /dev/null +++ b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording.js @@ -0,0 +1,6 @@ +import Route from '@ember/routing/route'; + +export default class ScopesScopeSessionRecordingsSessionRecordingRoute extends Route { + // =services + // =methods +} diff --git a/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/index.js b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/index.js new file mode 100644 index 000000000..000b3e322 --- /dev/null +++ b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/index.js @@ -0,0 +1,3 @@ +import Route from '@ember/routing/route'; + +export default class ScopesScopeSessionRecordingsSessionRecordingIndexRoute extends Route {} diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording.hbs new file mode 100644 index 000000000..7d32ecb0d --- /dev/null +++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording.hbs @@ -0,0 +1,3 @@ +{{page-title @model.displayName}} + +{{outlet}} \ No newline at end of file diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs new file mode 100644 index 000000000..e69de29bb diff --git a/ui/admin/tests/unit/routes/scopes/scope/session-recordings/session-recording-test.js b/ui/admin/tests/unit/routes/scopes/scope/session-recordings/session-recording-test.js new file mode 100644 index 000000000..1c9ccdb2b --- /dev/null +++ b/ui/admin/tests/unit/routes/scopes/scope/session-recordings/session-recording-test.js @@ -0,0 +1,16 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'admin/tests/helpers'; + +module( + 'Unit | Route | scopes/scope/session-recordings/session-recording', + function (hooks) { + setupTest(hooks); + + test('it exists', function (assert) { + let route = this.owner.lookup( + 'route:scopes/scope/session-recordings/session-recording' + ); + assert.ok(route); + }); + } +); diff --git a/ui/admin/tests/unit/routes/scopes/scope/session-recordings/session-recording/index-test.js b/ui/admin/tests/unit/routes/scopes/scope/session-recordings/session-recording/index-test.js new file mode 100644 index 000000000..d57fbb527 --- /dev/null +++ b/ui/admin/tests/unit/routes/scopes/scope/session-recordings/session-recording/index-test.js @@ -0,0 +1,16 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'admin/tests/helpers'; + +module( + 'Unit | Route | scopes/scope/session-recordings/session-recording/index', + function (hooks) { + setupTest(hooks); + + test('it exists', function (assert) { + let route = this.owner.lookup( + 'route:scopes/scope/session-recordings/session-recording/index' + ); + assert.ok(route); + }); + } +); From 458e02b23ab6c77175225f9623501f2a6d01e518 Mon Sep 17 00:00:00 2001 From: Devon Anderson Date: Tue, 28 Feb 2023 13:03:58 -0500 Subject: [PATCH 006/193] Update session-recordings.js --- ui/admin/app/routes/scopes/scope/session-recordings.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/ui/admin/app/routes/scopes/scope/session-recordings.js b/ui/admin/app/routes/scopes/scope/session-recordings.js index 8713f2966..4cca21156 100644 --- a/ui/admin/app/routes/scopes/scope/session-recordings.js +++ b/ui/admin/app/routes/scopes/scope/session-recordings.js @@ -29,8 +29,6 @@ export default class ScopesScopeSessionRecordingsRoute extends Route { // if (this.can.can('list session-recording', scope, { collection: 'session-recordings' })) { // return this.store.query('session-recording', { scope_id }); // } - - return 'i am session-recordings'; } // =actions From 463190650874a38298e419c8331c202e40189764 Mon Sep 17 00:00:00 2001 From: lisbet-alvarez <107949262+lisbet-alvarez@users.noreply.github.com> Date: Tue, 28 Feb 2023 13:20:31 -0800 Subject: [PATCH 007/193] add storage buckets route (#82) --- addons/core/translations/resources/en-us.yaml | 3 +++ ui/admin/app/router.js | 1 + .../session-recordings/storage-buckets.js | 19 +++++++++++++++++++ .../storage-buckets/index.js | 3 +++ .../scopes/scope/session-recordings.hbs | 2 +- .../session-recordings/storage-buckets.hbs | 3 +++ .../storage-buckets/index.hbs | 0 .../storage-buckets-test.js | 11 +++++++++++ .../storage-buckets/index-test.js | 11 +++++++++++ 9 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 ui/admin/app/routes/scopes/scope/session-recordings/storage-buckets.js create mode 100644 ui/admin/app/routes/scopes/scope/session-recordings/storage-buckets/index.js create mode 100644 ui/admin/app/templates/scopes/scope/session-recordings/storage-buckets.hbs create mode 100644 ui/admin/app/templates/scopes/scope/session-recordings/storage-buckets/index.hbs create mode 100644 ui/admin/tests/unit/routes/scopes/scope/session-recordings/storage-buckets-test.js create mode 100644 ui/admin/tests/unit/routes/scopes/scope/session-recordings/storage-buckets/index-test.js diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml index 8814160a6..fef732e7d 100644 --- a/addons/core/translations/resources/en-us.yaml +++ b/addons/core/translations/resources/en-us.yaml @@ -214,6 +214,9 @@ session-recordings: recorded-sessions: title: Recorded Session title_plural: Recorded Sessions + storage-bucket: + title: Storage Bucket + title_plural: Storage Buckets project: title: Project title_plural: Projects diff --git a/ui/admin/app/router.js b/ui/admin/app/router.js index 52a5ca380..9f052ad89 100644 --- a/ui/admin/app/router.js +++ b/ui/admin/app/router.js @@ -138,6 +138,7 @@ Router.map(function () { { path: ':session_recording_id' }, function () {} ); + this.route('storage-buckets', function() {}); }); }); }); diff --git a/ui/admin/app/routes/scopes/scope/session-recordings/storage-buckets.js b/ui/admin/app/routes/scopes/scope/session-recordings/storage-buckets.js new file mode 100644 index 000000000..14e19a947 --- /dev/null +++ b/ui/admin/app/routes/scopes/scope/session-recordings/storage-buckets.js @@ -0,0 +1,19 @@ +import Route from '@ember/routing/route'; + +export default class ScopesScopeSessionRecordingsStorageBucketsRoute extends Route { + // =services + + // TODO: store, can, and router services + + // =methods + + /** + * Loads all storage buckets under global and org scopes. + * @returns {Promise[StorageBucketModel]} + */ + // TODO: async model hook + + // =actions + + // TODO: save, cancel, and delete actions +} diff --git a/ui/admin/app/routes/scopes/scope/session-recordings/storage-buckets/index.js b/ui/admin/app/routes/scopes/scope/session-recordings/storage-buckets/index.js new file mode 100644 index 000000000..b7ab4668d --- /dev/null +++ b/ui/admin/app/routes/scopes/scope/session-recordings/storage-buckets/index.js @@ -0,0 +1,3 @@ +import Route from '@ember/routing/route'; + +export default class ScopesScopeSessionRecordingsStorageBucketsIndexRoute extends Route {} diff --git a/ui/admin/app/templates/scopes/scope/session-recordings.hbs b/ui/admin/app/templates/scopes/scope/session-recordings.hbs index 8a94562e7..cff117f14 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings.hbs @@ -1,2 +1,2 @@ -{{page-title (t 'resources.session-recording.title_plural')}} +{{page-title (t 'resources.session-recordings.title_plural')}} {{outlet}} \ No newline at end of file diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/storage-buckets.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/storage-buckets.hbs new file mode 100644 index 000000000..343dc50e5 --- /dev/null +++ b/ui/admin/app/templates/scopes/scope/session-recordings/storage-buckets.hbs @@ -0,0 +1,3 @@ +{{page-title (t 'resources.session-recordings.storage-bucket.title_plural')}} + +{{outlet}} \ No newline at end of file diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/storage-buckets/index.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/storage-buckets/index.hbs new file mode 100644 index 000000000..e69de29bb diff --git a/ui/admin/tests/unit/routes/scopes/scope/session-recordings/storage-buckets-test.js b/ui/admin/tests/unit/routes/scopes/scope/session-recordings/storage-buckets-test.js new file mode 100644 index 000000000..2a85b533d --- /dev/null +++ b/ui/admin/tests/unit/routes/scopes/scope/session-recordings/storage-buckets-test.js @@ -0,0 +1,11 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'admin/tests/helpers'; + +module('Unit | Route | scopes/scope/session-recordings/storage-buckets', function (hooks) { + setupTest(hooks); + + test('it exists', function (assert) { + let route = this.owner.lookup('route:scopes/scope/session-recordings/storage-buckets'); + assert.ok(route); + }); +}); diff --git a/ui/admin/tests/unit/routes/scopes/scope/session-recordings/storage-buckets/index-test.js b/ui/admin/tests/unit/routes/scopes/scope/session-recordings/storage-buckets/index-test.js new file mode 100644 index 000000000..1252f2956 --- /dev/null +++ b/ui/admin/tests/unit/routes/scopes/scope/session-recordings/storage-buckets/index-test.js @@ -0,0 +1,11 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'admin/tests/helpers'; + +module('Unit | Route | scopes/scope/session-recordings/storage-buckets/index', function (hooks) { + setupTest(hooks); + + test('it exists', function (assert) { + let route = this.owner.lookup('route:scopes/scope/session-recordings/storage-buckets/index'); + assert.ok(route); + }); +}); From c74d53931cd88697cecb9a0d6be07283ea105fc4 Mon Sep 17 00:00:00 2001 From: Cameron Perera Date: Wed, 1 Mar 2023 15:58:59 -0600 Subject: [PATCH 008/193] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20create=20routes?= =?UTF-8?q?=20for=20session-recording=20and=20channels=20(#89)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 🎸 create routes for session-recording and channels βœ… Closes: ICU-8241 * refactor: πŸ’‘ add hardcoded ids to make route navigation possible these are temporary and will be removed upon feature completion * refactor: πŸ’‘ rename channels route to channels-by-connection --- addons/core/translations/resources/en-us.yaml | 3 +++ ui/admin/app/router.js | 8 ++++++-- .../session-recordings/session-recording.js | 5 +++++ .../session-recording/channels-by-connection.js | 3 +++ .../channels-by-connection/channel.js | 9 +++++++++ .../channels-by-connection/index.js | 3 +++ .../session-recordings/session-recording.hbs | 1 + .../session-recording/channels-by-connection.hbs | 3 +++ .../channels-by-connection/channel.hbs | 4 ++++ .../channels-by-connection/index.hbs | 0 .../channels-by-connection-test.js | 16 ++++++++++++++++ .../channels-by-connection/channel-test.js | 16 ++++++++++++++++ .../channels-by-connection/index-test.js | 16 ++++++++++++++++ 13 files changed, 85 insertions(+), 2 deletions(-) create mode 100644 ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection.js create mode 100644 ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.js create mode 100644 ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/index.js create mode 100644 ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection.hbs create mode 100644 ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs create mode 100644 ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/index.hbs create mode 100644 ui/admin/tests/unit/routes/scopes/scope/session-recordings/session-recording/channels-by-connection-test.js create mode 100644 ui/admin/tests/unit/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel-test.js create mode 100644 ui/admin/tests/unit/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/index-test.js diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml index 2299d7ebe..e17787053 100644 --- a/addons/core/translations/resources/en-us.yaml +++ b/addons/core/translations/resources/en-us.yaml @@ -220,6 +220,9 @@ session-recordings: storage-bucket: title: Storage Bucket title_plural: Storage Buckets + channel: + title: Channel + title_plural: Channels project: title: Project title_plural: Projects diff --git a/ui/admin/app/router.js b/ui/admin/app/router.js index 34ad6fd25..41947d0f4 100644 --- a/ui/admin/app/router.js +++ b/ui/admin/app/router.js @@ -141,9 +141,13 @@ Router.map(function () { this.route( 'session-recording', { path: ':session_recording_id' }, - function () {} + function () { + this.route('channels-by-connection', function () { + this.route('channel', { path: ':channel_id' }, function () {}); + }); + } ); - this.route('storage-buckets', function() {}); + this.route('storage-buckets', function () {}); }); }); }); diff --git a/ui/admin/app/routes/scopes/scope/session-recordings/session-recording.js b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording.js index 9224bab43..0c76fa6df 100644 --- a/ui/admin/app/routes/scopes/scope/session-recordings/session-recording.js +++ b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording.js @@ -3,4 +3,9 @@ import Route from '@ember/routing/route'; export default class ScopesScopeSessionRecordingsSessionRecordingRoute extends Route { // =services // =methods + model() { + return { + scope_id: 'sr_1234567890', + }; + } } diff --git a/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection.js b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection.js new file mode 100644 index 000000000..9513ee879 --- /dev/null +++ b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection.js @@ -0,0 +1,3 @@ +import Route from '@ember/routing/route'; + +export default class ScopesScopeSessionRecordingsSessionRecordingChannelsByConnectionRoute extends Route {} diff --git a/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.js b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.js new file mode 100644 index 000000000..495eee914 --- /dev/null +++ b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.js @@ -0,0 +1,9 @@ +import Route from '@ember/routing/route'; + +export default class ScopesScopeSessionRecordingsSessionRecordingChannelsByConnectionChannelRoute extends Route { + model() { + return { + scope_id: 'srcc_1234567890', + }; + } +} diff --git a/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/index.js b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/index.js new file mode 100644 index 000000000..2a6ddf3a4 --- /dev/null +++ b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/index.js @@ -0,0 +1,3 @@ +import Route from '@ember/routing/route'; + +export default class ScopesScopeSessionRecordingsSessionRecordingChannelsByConnectionIndexRoute extends Route {} diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording.hbs index 7d32ecb0d..4c1ce9936 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording.hbs @@ -1,3 +1,4 @@ {{page-title @model.displayName}} +

{{@model.scope_id}}

{{outlet}} \ No newline at end of file diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection.hbs new file mode 100644 index 000000000..708976b2e --- /dev/null +++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection.hbs @@ -0,0 +1,3 @@ +{{page-title (t 'resources.session-recordings.channel.title_plural')}} + +{{outlet}} \ No newline at end of file diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs new file mode 100644 index 000000000..c7f8e0163 --- /dev/null +++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs @@ -0,0 +1,4 @@ +{{page-title (t 'resources.session-recordings.channel.title')}} + +

{{@model.scope_id}}

+{{outlet}} \ No newline at end of file diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/index.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/index.hbs new file mode 100644 index 000000000..e69de29bb diff --git a/ui/admin/tests/unit/routes/scopes/scope/session-recordings/session-recording/channels-by-connection-test.js b/ui/admin/tests/unit/routes/scopes/scope/session-recordings/session-recording/channels-by-connection-test.js new file mode 100644 index 000000000..8b04301d1 --- /dev/null +++ b/ui/admin/tests/unit/routes/scopes/scope/session-recordings/session-recording/channels-by-connection-test.js @@ -0,0 +1,16 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'admin/tests/helpers'; + +module( + 'Unit | Route | scopes/scope/session-recordings/session-recording/channels-by-connection', + function (hooks) { + setupTest(hooks); + + test('it exists', function (assert) { + let route = this.owner.lookup( + 'route:scopes/scope/session-recordings/session-recording/channels-by-connection' + ); + assert.ok(route); + }); + } +); diff --git a/ui/admin/tests/unit/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel-test.js b/ui/admin/tests/unit/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel-test.js new file mode 100644 index 000000000..3ca0c9afb --- /dev/null +++ b/ui/admin/tests/unit/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel-test.js @@ -0,0 +1,16 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'admin/tests/helpers'; + +module( + 'Unit | Route | scopes/scope/session-recordings/session-recording/channels-by-connection/channel', + function (hooks) { + setupTest(hooks); + + test('it exists', function (assert) { + let route = this.owner.lookup( + 'route:scopes/scope/session-recordings/session-recording/channels-by-connection/channel' + ); + assert.ok(route); + }); + } +); diff --git a/ui/admin/tests/unit/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/index-test.js b/ui/admin/tests/unit/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/index-test.js new file mode 100644 index 000000000..c6d4d870a --- /dev/null +++ b/ui/admin/tests/unit/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/index-test.js @@ -0,0 +1,16 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'admin/tests/helpers'; + +module( + 'Unit | Route | scopes/scope/session-recordings/session-recording/channels-by-connection/index', + function (hooks) { + setupTest(hooks); + + test('it exists', function (assert) { + let route = this.owner.lookup( + 'route:scopes/scope/session-recordings/session-recording/channels-by-connection/index' + ); + assert.ok(route); + }); + } +); From 32e7b45f4ae335b069d25813facc8328adc2fd7d Mon Sep 17 00:00:00 2001 From: Devon Anderson Date: Thu, 2 Mar 2023 10:08:13 -0500 Subject: [PATCH 009/193] =?UTF-8?q?refactor:=20=F0=9F=92=A1=20revise=20sto?= =?UTF-8?q?rage=20buckets=20route=20(#86)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: πŸ’‘ revise storage buckets route Move `storage-buckets` route outside of nested `session-recordings` βœ… Closes: ICU-8307 * Update en-us.yaml removed unneeded resource * Update en-us.yaml * refactor: πŸ’‘ clean up translations Cleaned up multiple readable strings in translations. βœ… Closes: ICU-8307 --- addons/core/translations/resources/en-us.yaml | 15 ++++++--------- ui/admin/app/router.js | 2 +- .../session-recordings/storage-buckets.js | 19 ------------------- .../storage-buckets/index.js | 3 --- .../routes/scopes/scope/storage-buckets.js | 3 +++ .../scopes/scope/storage-buckets/index.js | 3 +++ .../scopes/scope/session-recordings.hbs | 3 ++- .../session-recordings/storage-buckets.hbs | 3 --- .../scopes/scope/storage-buckets.hbs | 3 +++ .../storage-buckets/index.hbs | 0 .../storage-buckets-test.js | 11 ----------- .../storage-buckets/index-test.js | 11 ----------- .../scopes/scope/storage-buckets-test.js | 11 +++++++++++ .../scope/storage-buckets/index-test.js | 11 +++++++++++ 14 files changed, 40 insertions(+), 58 deletions(-) delete mode 100644 ui/admin/app/routes/scopes/scope/session-recordings/storage-buckets.js delete mode 100644 ui/admin/app/routes/scopes/scope/session-recordings/storage-buckets/index.js create mode 100644 ui/admin/app/routes/scopes/scope/storage-buckets.js create mode 100644 ui/admin/app/routes/scopes/scope/storage-buckets/index.js delete mode 100644 ui/admin/app/templates/scopes/scope/session-recordings/storage-buckets.hbs create mode 100644 ui/admin/app/templates/scopes/scope/storage-buckets.hbs rename ui/admin/app/templates/scopes/scope/{session-recordings => }/storage-buckets/index.hbs (100%) delete mode 100644 ui/admin/tests/unit/routes/scopes/scope/session-recordings/storage-buckets-test.js delete mode 100644 ui/admin/tests/unit/routes/scopes/scope/session-recordings/storage-buckets/index-test.js create mode 100644 ui/admin/tests/unit/routes/scopes/scope/storage-buckets-test.js create mode 100644 ui/admin/tests/unit/routes/scopes/scope/storage-buckets/index-test.js diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml index e17787053..11ef2d88b 100644 --- a/addons/core/translations/resources/en-us.yaml +++ b/addons/core/translations/resources/en-us.yaml @@ -211,18 +211,15 @@ org: new: New Org actions: delete: Delete Org -session-recordings: - title: Session Recording - title_plural: Session Recordings - recorded-sessions: - title: Recorded Session - title_plural: Recorded Sessions - storage-bucket: - title: Storage Bucket - title_plural: Storage Buckets +session-recording: + title: Recorded Session + title_plural: Recorded Sessions channel: title: Channel title_plural: Channels +storage-bucket: + title: Storage Bucket + title_plural: Storage Buckets project: title: Project title_plural: Projects diff --git a/ui/admin/app/router.js b/ui/admin/app/router.js index 41947d0f4..26ba1f57b 100644 --- a/ui/admin/app/router.js +++ b/ui/admin/app/router.js @@ -147,8 +147,8 @@ Router.map(function () { }); } ); - this.route('storage-buckets', function () {}); }); + this.route('storage-buckets', function () {}); }); }); diff --git a/ui/admin/app/routes/scopes/scope/session-recordings/storage-buckets.js b/ui/admin/app/routes/scopes/scope/session-recordings/storage-buckets.js deleted file mode 100644 index 14e19a947..000000000 --- a/ui/admin/app/routes/scopes/scope/session-recordings/storage-buckets.js +++ /dev/null @@ -1,19 +0,0 @@ -import Route from '@ember/routing/route'; - -export default class ScopesScopeSessionRecordingsStorageBucketsRoute extends Route { - // =services - - // TODO: store, can, and router services - - // =methods - - /** - * Loads all storage buckets under global and org scopes. - * @returns {Promise[StorageBucketModel]} - */ - // TODO: async model hook - - // =actions - - // TODO: save, cancel, and delete actions -} diff --git a/ui/admin/app/routes/scopes/scope/session-recordings/storage-buckets/index.js b/ui/admin/app/routes/scopes/scope/session-recordings/storage-buckets/index.js deleted file mode 100644 index b7ab4668d..000000000 --- a/ui/admin/app/routes/scopes/scope/session-recordings/storage-buckets/index.js +++ /dev/null @@ -1,3 +0,0 @@ -import Route from '@ember/routing/route'; - -export default class ScopesScopeSessionRecordingsStorageBucketsIndexRoute extends Route {} diff --git a/ui/admin/app/routes/scopes/scope/storage-buckets.js b/ui/admin/app/routes/scopes/scope/storage-buckets.js new file mode 100644 index 000000000..9d17270e6 --- /dev/null +++ b/ui/admin/app/routes/scopes/scope/storage-buckets.js @@ -0,0 +1,3 @@ +import Route from '@ember/routing/route'; + +export default class ScopesScopeStorageBucketsRoute extends Route {} diff --git a/ui/admin/app/routes/scopes/scope/storage-buckets/index.js b/ui/admin/app/routes/scopes/scope/storage-buckets/index.js new file mode 100644 index 000000000..e27e0a0dc --- /dev/null +++ b/ui/admin/app/routes/scopes/scope/storage-buckets/index.js @@ -0,0 +1,3 @@ +import Route from '@ember/routing/route'; + +export default class ScopesScopeStorageBucketsIndexRoute extends Route {} diff --git a/ui/admin/app/templates/scopes/scope/session-recordings.hbs b/ui/admin/app/templates/scopes/scope/session-recordings.hbs index cff117f14..fde0c392e 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings.hbs @@ -1,2 +1,3 @@ -{{page-title (t 'resources.session-recordings.title_plural')}} +{{page-title (t 'resources.session-recording.title_plural')}} + {{outlet}} \ No newline at end of file diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/storage-buckets.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/storage-buckets.hbs deleted file mode 100644 index 343dc50e5..000000000 --- a/ui/admin/app/templates/scopes/scope/session-recordings/storage-buckets.hbs +++ /dev/null @@ -1,3 +0,0 @@ -{{page-title (t 'resources.session-recordings.storage-bucket.title_plural')}} - -{{outlet}} \ No newline at end of file diff --git a/ui/admin/app/templates/scopes/scope/storage-buckets.hbs b/ui/admin/app/templates/scopes/scope/storage-buckets.hbs new file mode 100644 index 000000000..5fda700a0 --- /dev/null +++ b/ui/admin/app/templates/scopes/scope/storage-buckets.hbs @@ -0,0 +1,3 @@ +{{page-title (t 'resources.storage-bucket.title_plural')}} + +{{outlet}} \ No newline at end of file diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/storage-buckets/index.hbs b/ui/admin/app/templates/scopes/scope/storage-buckets/index.hbs similarity index 100% rename from ui/admin/app/templates/scopes/scope/session-recordings/storage-buckets/index.hbs rename to ui/admin/app/templates/scopes/scope/storage-buckets/index.hbs diff --git a/ui/admin/tests/unit/routes/scopes/scope/session-recordings/storage-buckets-test.js b/ui/admin/tests/unit/routes/scopes/scope/session-recordings/storage-buckets-test.js deleted file mode 100644 index 2a85b533d..000000000 --- a/ui/admin/tests/unit/routes/scopes/scope/session-recordings/storage-buckets-test.js +++ /dev/null @@ -1,11 +0,0 @@ -import { module, test } from 'qunit'; -import { setupTest } from 'admin/tests/helpers'; - -module('Unit | Route | scopes/scope/session-recordings/storage-buckets', function (hooks) { - setupTest(hooks); - - test('it exists', function (assert) { - let route = this.owner.lookup('route:scopes/scope/session-recordings/storage-buckets'); - assert.ok(route); - }); -}); diff --git a/ui/admin/tests/unit/routes/scopes/scope/session-recordings/storage-buckets/index-test.js b/ui/admin/tests/unit/routes/scopes/scope/session-recordings/storage-buckets/index-test.js deleted file mode 100644 index 1252f2956..000000000 --- a/ui/admin/tests/unit/routes/scopes/scope/session-recordings/storage-buckets/index-test.js +++ /dev/null @@ -1,11 +0,0 @@ -import { module, test } from 'qunit'; -import { setupTest } from 'admin/tests/helpers'; - -module('Unit | Route | scopes/scope/session-recordings/storage-buckets/index', function (hooks) { - setupTest(hooks); - - test('it exists', function (assert) { - let route = this.owner.lookup('route:scopes/scope/session-recordings/storage-buckets/index'); - assert.ok(route); - }); -}); diff --git a/ui/admin/tests/unit/routes/scopes/scope/storage-buckets-test.js b/ui/admin/tests/unit/routes/scopes/scope/storage-buckets-test.js new file mode 100644 index 000000000..59c84d020 --- /dev/null +++ b/ui/admin/tests/unit/routes/scopes/scope/storage-buckets-test.js @@ -0,0 +1,11 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'admin/tests/helpers'; + +module('Unit | Route | scopes/scope/storage-buckets', function (hooks) { + setupTest(hooks); + + test('it exists', function (assert) { + let route = this.owner.lookup('route:scopes/scope/storage-buckets'); + assert.ok(route); + }); +}); diff --git a/ui/admin/tests/unit/routes/scopes/scope/storage-buckets/index-test.js b/ui/admin/tests/unit/routes/scopes/scope/storage-buckets/index-test.js new file mode 100644 index 000000000..4c19c6e24 --- /dev/null +++ b/ui/admin/tests/unit/routes/scopes/scope/storage-buckets/index-test.js @@ -0,0 +1,11 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'admin/tests/helpers'; + +module('Unit | Route | scopes/scope/storage-buckets/index', function (hooks) { + setupTest(hooks); + + test('it exists', function (assert) { + let route = this.owner.lookup('route:scopes/scope/storage-buckets/index'); + assert.ok(route); + }); +}); From 75f0192540c3ee457b2bb737f0ab568332eda597 Mon Sep 17 00:00:00 2001 From: Cameron Perera Date: Thu, 2 Mar 2023 15:56:47 -0600 Subject: [PATCH 010/193] Icu 8328 import ember asciinema player (#93) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: πŸ€– add @hashicorp/ember-asciinema-player to admin UI βœ… Closes: ICU-8328 * feat: 🎸 show ember-asciinema player in channels view * chore: πŸ€– remove @hashicorp/ember-asciinema-player as dependency * chore: πŸ€– fix ember-asciinema-player source URL for install * chore: πŸ€– update yarn.lock --- package.json | 2 +- .../channels-by-connection/channel.js | 5 +- ui/admin/app/styles/app.scss | 1 + .../channels-by-connection/channel.hbs | 3 + ui/admin/package.json | 1 + ui/admin/public/session.cast | 69 +++++++++ yarn.lock | 136 +++++++++++++++++- 7 files changed, 210 insertions(+), 7 deletions(-) create mode 100644 ui/admin/public/session.cast diff --git a/package.json b/package.json index c11d1ec1d..967395350 100755 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "test:addons-rose": "yarn --cwd addons/rose test", "test:ui-admin": "yarn --cwd ui/admin test", "test:ui-desktop": "yarn --cwd ui/desktop test", - "compliance:licenses": "license-checker --onlyAllow 'Apache*;Apache License, Version 2.0;Apache-2.0;Apache 2.0;Artistic-2.0;BSD;BSD-3-Clause;CC-BY-3.0;CC-BY-4.0;CC0-1.0;ISC;MIT;MPL-2.0;Public Domain;Python-2.0;Unicode-TOU;Unlicense;WTFPL' --excludePackages 'boundary-ui;admin@0.0.0;desktop@0.0.0;base64-js@0.0.2;cycle@1.0.3;cldr-core@41.0.0;make-plural@7.2.0'", + "compliance:licenses": "license-checker --onlyAllow 'Apache*;Apache License, Version 2.0;Apache-2.0;Apache 2.0;Artistic-2.0;BSD;BSD-3-Clause;CC-BY-3.0;CC-BY-4.0;CC0-1.0;ISC;MIT;MPL-2.0;Public Domain;Python-2.0;Unicode-TOU;Unlicense;WTFPL' --excludePackages 'boundary-ui;admin@0.0.0;desktop@0.0.0;base64-js@0.0.2;cycle@1.0.3;cldr-core@41.0.0;make-plural@7.2.0;@hashicorp/ember-asciinema-player@0.0.0'", "doc:toc": "doctoc README.md", "prepare": "husky install" }, diff --git a/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.js b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.js index 495eee914..0db1b6ae4 100644 --- a/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.js +++ b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.js @@ -1,9 +1,12 @@ import Route from '@ember/routing/route'; export default class ScopesScopeSessionRecordingsSessionRecordingChannelsByConnectionChannelRoute extends Route { - model() { + async model() { + const response = await fetch('/session.cast'); + const asciicast = await response.text(); return { scope_id: 'srcc_1234567890', + asciicast: asciicast, }; } } diff --git a/ui/admin/app/styles/app.scss b/ui/admin/app/styles/app.scss index af13179a1..1f305e001 100644 --- a/ui/admin/app/styles/app.scss +++ b/ui/admin/app/styles/app.scss @@ -9,6 +9,7 @@ @import 'rose'; @import 'notify'; +@import '@hashicorp/ember-asciinema-player'; .rose-layout-global { .rose-layout-global-body { diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs index c7f8e0163..0aa78b6e8 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs @@ -1,4 +1,7 @@ {{page-title (t 'resources.session-recordings.channel.title')}}

{{@model.scope_id}}

+
+ +
{{outlet}} \ No newline at end of file diff --git a/ui/admin/package.json b/ui/admin/package.json index 06d8f63ba..4f0273108 100644 --- a/ui/admin/package.json +++ b/ui/admin/package.json @@ -52,6 +52,7 @@ "@faker-js/faker": "^7.3.0", "@glimmer/component": "^1.1.2", "@glimmer/tracking": "^1.1.2", + "@hashicorp/ember-asciinema-player": "https://github.com/hashicorp/ember-asciinema-player.git", "@playwright/test": "^1.30.0", "babel-loader": "^8.2.5", "broccoli-asset-rev": "^3.0.0", diff --git a/ui/admin/public/session.cast b/ui/admin/public/session.cast new file mode 100644 index 000000000..698962492 --- /dev/null +++ b/ui/admin/public/session.cast @@ -0,0 +1,69 @@ +{"version": 2, "width": 124, "height": 36, "timestamp": 1670352594, "env": {"SHELL": "/bin/zsh", "TERM": "xterm-256color"}} +[2.138652, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r\u001b]2;ember-asciinema-player\u0007\u001b]1;..iinema-player\u0007"] +[2.220877, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\u001b[33member-asciinema-player\u001b[00m \u001b[32mgit\u001b[00m:\u001b[36m(main*)\u001b[00m $ \u001b[K"] +[2.221019, "o", "\u001b[?1h\u001b="] +[2.221076, "o", "\u001b[?2004h"] +[2.676444, "o", "y"] +[2.788653, "o", "\bya"] +[2.868652, "o", "r"] +[3.001764, "o", "n"] +[3.167636, "o", " "] +[3.313668, "o", "t"] +[3.460527, "o", "e"] +[3.561983, "o", "s"] +[3.63678, "o", "t"] +[3.853437, "o", "\u001b[?1l\u001b>"] +[3.853473, "o", "\u001b[?2004l\r\r\n"] +[3.854604, "o", "\u001b]2;yarn test\u0007\u001b]1;yarn\u0007"] +[4.489178, "o", "\u001b[2K"] +[4.48982, "o", "\u001b[1G\u001b[1myarn run v1.22.19\u001b[22m\r\n"] +[4.555618, "o", "\u001b[2K"] +[4.555649, "o", "\u001b[1G\u001b[2m$ npm-run-all lint\u001b[22m\r\n"] +[5.345253, "o", "\u001b[2K"] +[5.345509, "o", "\u001b[1G\u001b[2m$ npm-run-all --print-name --aggregate-output --continue-on-error --parallel \"lint:!(fix)\"\u001b[22m\r\n"] +[7.225926, "o", "\r\n> ember-asciinema-player@0.0.0 lint:js ember-asciinema-player/package.json\r\n> eslint . --cache \r\n\r\n$ eslint . --cache\r\n"] +[8.398641, "o", "\r\n> ember-asciinema-player@0.0.0 lint:hbs ember-asciinema-player/package.json\r\n> ember-template-lint . \r\n\r\n$ ember-template-lint .\r\n\r\n"] +[8.418537, "o", "\u001b[2K\u001b[1G\u001b[2m$ ember test\u001b[22m\r\n"] +[12.256156, "o", "\u001b[?25l"] +[12.256464, "o", "\u001b[32mβ ‹\u001b[39m \u001b[32mBuilding\u001b[39m"] +[12.2573, "o", "\u001b[2K"] +[12.257386, "o", "\u001b[1G\u001b[?25h"] +[12.257689, "o", "Environment: test\r\n"] +[12.257857, "o", "\u001b[?25l\u001b[32mβ ‹\u001b[39m \u001b[32mBuilding\u001b[39m"] +[12.539035, "o", "\u001b[2K"] +[12.539144, "o", "\u001b[1G"] +[12.539219, "o", "\u001b[32mβ ™\u001b[39m \u001b[32mbuilding... \u001b[39m"] +[12.745202, "o", "\u001b[2K\u001b[1G"] +[12.745343, "o", "\u001b[32mβ Ή\u001b[39m \u001b[32mbuilding... \u001b[39m[Babel: @ember/test-helpers > applyPatches]"] +[12.825004, "o", "\u001b[2K"] +[12.825031, "o", "\u001b[1G"] +[12.825122, "o", "\u001b[32mβ Έ\u001b[39m \u001b[32mbuilding... \u001b[39m[Babel: ember-qunit > applyPatches]"] +[12.933588, "o", "\u001b[2K\u001b[1G"] +[12.933624, "o", "\u001b[32mβ Ό\u001b[39m \u001b[32mbuilding... \u001b[39m[Babel: ember-load-initializers > applyPatches]"] +[13.194738, "o", "\u001b[2K\u001b[1G"] +[13.195009, "o", "\u001b[32mβ ΄\u001b[39m \u001b[32mbuilding... \u001b[39m[Babel: ember-asciinema-player > applyPatches]"] +[13.307878, "o", "\u001b[2K\u001b[1G\u001b[32mβ ¦\u001b[39m \u001b[32mbuilding... \u001b[39m[Package /assets/vendor.js]"] +[13.750717, "o", "\u001b[2K\u001b[1G"] +[13.750755, "o", "\u001b[32mβ §\u001b[39m \u001b[32mbuilding... \u001b[39m[Concat: Test Support JS]"] +[13.869411, "o", "\u001b[2K\u001b[1G"] +[13.869438, "o", "\u001b[32mβ ‡\u001b[39m \u001b[32mbuilding... \u001b[39m[ember-auto-import-webpack]"] +[14.655374, "o", "\u001b[2K\u001b[1G"] +[14.655415, "o", "\u001b[32m⠏\u001b[39m \u001b[32mbuilding... \u001b[39m[ember-auto-import-webpack]"] +[14.73686, "o", "\u001b[2K\u001b[1G\u001b[?25h"] +[14.738533, "o", "\u001b[?25h"] +[14.738818, "o", "\u001b[?25l\u001b[32mβ ‹\u001b[39m cleaning up"] +[14.739061, "o", "\u001b[2K\u001b[1G\u001b[?25hcleaning up...\r\n"] +[14.739197, "o", "\u001b[?25l\u001b[32mβ ‹\u001b[39m cleaning up"] +[14.907985, "o", "\u001b[2K"] +[14.90808, "o", "\u001b[1G\u001b[?25h"] +[14.908128, "o", "\u001b[32mBuilt project successfully.\u001b[39m\r\n"] +[16.224632, "o", "ok 1 Chrome 108.0 - [2 ms] - ember-qunit: Ember.onerror validation: Ember.onerror is functioning properly\r\n"] +[16.346568, "o", "\r\n1..1\r\n# tests 1\r\n# pass 1\r\n# skip 0\r\n# todo 0\r\n# fail 0\r\n\r\n# ok\r\n"] +[16.403167, "o", "\u001b[2K"] +[16.403388, "o", "\u001b[1G✨ Done in 11.92s.\r\n"] +[16.413967, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"] +[16.414147, "o", "\u001b]2;ember-asciinema-player\u0007\u001b]1;..iinema-player\u0007"] +[16.528341, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\u001b[33member-asciinema-player\u001b[00m \u001b[32mgit\u001b[00m:\u001b[36m(main*)\u001b[00m $ \u001b[K"] +[16.528501, "o", "\u001b[?1h\u001b="] +[16.52863, "o", "\u001b[?2004h"] +[19.078794, "o", "\u001b[?2004l\r\r\n"] \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 63d5b417d..75b1d2ce9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3295,6 +3295,13 @@ dependencies: regenerator-runtime "^0.13.4" +"@babel/runtime@^7.15.4": + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.0.tgz#5b55c9d394e5fcf304909a8b00c07dc217b56673" + integrity sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw== + dependencies: + regenerator-runtime "^0.13.11" + "@babel/template@^7.12.7", "@babel/template@^7.14.5": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.14.5.tgz#a9bc9d8b33354ff6e55a9c60d1109200a68974f4" @@ -4704,6 +4711,15 @@ resolved "https://registry.yarnpkg.com/@hashicorp/design-system-tokens/-/design-system-tokens-1.3.0.tgz#0a143f7fb20b72ac003e56c7408e23b0b55d45f9" integrity sha512-Re16f4tqyAApChk20Eev0xVWijCo8m3YYIo4A84tStTTkXk4d63lbY1MuebWaaAjcjzKGuyPh0w3u0SJWJFCUg== +"@hashicorp/ember-asciinema-player@https://github.com/hashicorp/ember-asciinema-player.git": + version "0.0.0" + resolved "https://github.com/hashicorp/ember-asciinema-player.git#28dac2ffdac6d6437735eb08751ea2a8f51007fe" + dependencies: + asciinema-player "^3.0.1" + ember-auto-import "^2.5.0" + ember-cli-babel "^7.26.11" + ember-cli-htmlbars "^6.1.1" + "@hashicorp/ember-flight-icons@^3.0.2": version "3.0.2" resolved "https://registry.yarnpkg.com/@hashicorp/ember-flight-icons/-/ember-flight-icons-3.0.2.tgz#8d884c07842a6c88df18ca680d7883a59222a2ba" @@ -8600,6 +8616,14 @@ asar@^3.1.0: optionalDependencies: "@types/glob" "^7.1.1" +asciinema-player@^3.0.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/asciinema-player/-/asciinema-player-3.1.1.tgz#bb1cfb5c4c1dc69605d318804050c53f090f1219" + integrity sha512-dEOV6eKS7no9cHDT7U2DhI6bcqqvBaxLgM3WvUnuVdFvj5BKIb4/5DDHmIeDk6ntByRRaGqu9KTUrh+MJ3Se8w== + dependencies: + "@babel/runtime" "^7.15.4" + solid-js "^1.3.0" + asn1.js@^5.2.0: version "5.4.1" resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-5.4.1.tgz#11a980b84ebb91781ce35b0fdc2ee294e3783f07" @@ -8827,6 +8851,11 @@ babel-import-util@^1.1.0: resolved "https://registry.yarnpkg.com/babel-import-util/-/babel-import-util-1.1.0.tgz#4156b16ef090c4f0d3cdb869ff799202f24aeb93" integrity sha512-sfzgAiJsUT1es9yrHAuJZuJfBkkOE7Og6rovAIwK/gNJX6MjDfWTprbPngdJZTd5ye4F3FvpvpQmvKXObRzVYA== +babel-import-util@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/babel-import-util/-/babel-import-util-1.3.0.tgz#dc9251ea39a7747bd586c1c13b8d785a42797f8e" + integrity sha512-PPzUT17eAI18zn6ek1R3sB4Krc/MbnmT1MkZQFmyhjoaEGBVwNABhfVU9+EKcDSKrrOm9OIpGhjxukx1GCiy1g== + babel-jest@^27.4.6: version "27.4.6" resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-27.4.6.tgz#4d024e69e241cdf4f396e453a07100f44f7ce314" @@ -8928,6 +8957,13 @@ babel-plugin-ember-template-compilation@^1.0.0: magic-string "^0.25.7" string.prototype.matchall "^4.0.5" +babel-plugin-ember-template-compilation@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/babel-plugin-ember-template-compilation/-/babel-plugin-ember-template-compilation-2.0.0.tgz#41d895874ba6119dd461f61993c16d1154bf8a57" + integrity sha512-d+4jaB2ik0rt9TH0K9kOlKJeRBHEb373FgFMcU9ZaJL2zYuVXe19bqy+cWlLpLf1tpOBcBG9QTlFBCoImlOt1g== + dependencies: + babel-import-util "^1.3.0" + babel-plugin-emotion@^10.0.27: version "10.2.2" resolved "https://registry.yarnpkg.com/babel-plugin-emotion/-/babel-plugin-emotion-10.2.2.tgz#a1fe3503cff80abfd0bdda14abd2e8e57a79d17d" @@ -11745,6 +11781,11 @@ csstype@^3.0.2: resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.8.tgz#d2266a792729fb227cd216fb572f43728e1ad340" integrity sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw== +csstype@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.1.tgz#841b532c45c758ee546a11d5bd7b7b473c8c30b9" + integrity sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw== + currently-unhandled@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" @@ -11864,7 +11905,7 @@ debug@^3.0.0, debug@^3.0.1, debug@^3.1.0, debug@^3.1.1, debug@^3.2.7: dependencies: ms "^2.1.1" -debuglog@^1.0.1: +debuglog@*, debuglog@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" integrity sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI= @@ -12662,6 +12703,42 @@ ember-auto-import@^2.4.0, ember-auto-import@^2.4.3: typescript-memoize "^1.0.0-alpha.3" walk-sync "^3.0.0" +ember-auto-import@^2.5.0: + version "2.6.1" + resolved "https://registry.yarnpkg.com/ember-auto-import/-/ember-auto-import-2.6.1.tgz#bd8d434143bd411b99f4a8f32d8b58414d7da4f3" + integrity sha512-3bCRi/pXp4QslmuCXGlSz9xwR7DF5oDx3zZO5OXKzNZihtkqAM1xvGuRIdQSl46pvbAXOkp8Odl5fOen1i0dRw== + dependencies: + "@babel/core" "^7.16.7" + "@babel/plugin-proposal-class-properties" "^7.16.7" + "@babel/plugin-proposal-decorators" "^7.16.7" + "@babel/preset-env" "^7.16.7" + "@embroider/macros" "^1.0.0" + "@embroider/shared-internals" "^2.0.0" + babel-loader "^8.0.6" + babel-plugin-ember-modules-api-polyfill "^3.5.0" + babel-plugin-htmlbars-inline-precompile "^5.2.1" + babel-plugin-syntax-dynamic-import "^6.18.0" + broccoli-debug "^0.6.4" + broccoli-funnel "^3.0.8" + broccoli-merge-trees "^4.2.0" + broccoli-plugin "^4.0.0" + broccoli-source "^3.0.0" + css-loader "^5.2.0" + debug "^4.3.1" + fs-extra "^10.0.0" + fs-tree-diff "^2.0.0" + handlebars "^4.3.1" + js-string-escape "^1.0.1" + lodash "^4.17.19" + mini-css-extract-plugin "^2.5.2" + parse5 "^6.0.1" + resolve "^1.20.0" + resolve-package-path "^4.0.3" + semver "^7.3.4" + style-loader "^2.0.0" + typescript-memoize "^1.0.0-alpha.3" + walk-sync "^3.0.0" + ember-autofocus-modifier@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/ember-autofocus-modifier/-/ember-autofocus-modifier-4.0.1.tgz#3ebfed826b2544831fd1e4b77540142cd4d3ac2b" @@ -12937,6 +13014,26 @@ ember-cli-htmlbars@^6.1.0: silent-error "^1.1.1" walk-sync "^2.2.0" +ember-cli-htmlbars@^6.1.1: + version "6.2.0" + resolved "https://registry.yarnpkg.com/ember-cli-htmlbars/-/ember-cli-htmlbars-6.2.0.tgz#18ec48ee1c93f9eed862a64eb24a9d14604f1dfc" + integrity sha512-j5EGixjGau23HrqRiW/JjoAovg5UBHfjbyN7wX5ekE90knIEqUUj1z/Mo/cTx/J2VepQ2lE6HdXW9LWQ/WdMtw== + dependencies: + "@ember/edition-utils" "^1.2.0" + babel-plugin-ember-template-compilation "^2.0.0" + babel-plugin-htmlbars-inline-precompile "^5.3.0" + broccoli-debug "^0.6.5" + broccoli-persistent-filter "^3.1.2" + broccoli-plugin "^4.0.3" + ember-cli-version-checker "^5.1.2" + fs-tree-diff "^2.0.1" + hash-for-dep "^1.5.1" + heimdalljs-logger "^0.1.10" + js-string-escape "^1.0.1" + semver "^7.3.4" + silent-error "^1.1.1" + walk-sync "^2.2.0" + ember-cli-inject-live-reload@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/ember-cli-inject-live-reload/-/ember-cli-inject-live-reload-2.1.0.tgz#ef63c733c133024d5726405a3c247fa12e88a385" @@ -17000,7 +17097,7 @@ import-local@^3.0.2: pkg-dir "^4.2.0" resolve-cwd "^3.0.0" -imurmurhash@^0.1.4: +imurmurhash@*, imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= @@ -19131,6 +19228,11 @@ lodash._baseflatten@^3.0.0: lodash.isarguments "^3.0.0" lodash.isarray "^3.0.0" +lodash._baseindexof@*: + version "3.1.0" + resolved "https://registry.yarnpkg.com/lodash._baseindexof/-/lodash._baseindexof-3.1.0.tgz#fe52b53a1c6761e42618d654e4a25789ed61822c" + integrity sha512-bSYo8Pc/f0qAkr8fPJydpJjtrHiSynYfYBjtANIgXv5xEf1WlTC63dIDlgu0s9dmTvzRu1+JJTxcIAHe+sH0FQ== + lodash._baseuniq@~4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash._baseuniq/-/lodash._baseuniq-4.6.0.tgz#0ebb44e456814af7905c6212fa2c9b2d51b841e8" @@ -19139,11 +19241,16 @@ lodash._baseuniq@~4.6.0: lodash._createset "~4.0.0" lodash._root "~3.0.0" -lodash._bindcallback@^3.0.0: +lodash._bindcallback@*, lodash._bindcallback@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz#e531c27644cf8b57a99e17ed95b35c748789392e" integrity sha512-2wlI0JRAGX8WEf4Gm1p/mv/SZ+jLijpj0jyaE/AXeuQphzCgD8ZQW4oSpoN8JAopujOFGU3KMuq7qfHBWlGpjQ== +lodash._cacheindexof@*: + version "3.0.2" + resolved "https://registry.yarnpkg.com/lodash._cacheindexof/-/lodash._cacheindexof-3.0.2.tgz#3dc69ac82498d2ee5e3ce56091bafd2adc7bde92" + integrity sha512-S8dUjWr7SUT/X6TBIQ/OYoCHo1Stu1ZRy6uMUSKqzFnZp5G5RyQizSm6kvxD2Ewyy6AVfMg4AToeZzKfF99T5w== + lodash._createassigner@^3.0.0: version "3.1.1" resolved "https://registry.yarnpkg.com/lodash._createassigner/-/lodash._createassigner-3.1.1.tgz#838a5bae2fdaca63ac22dee8e19fa4e6d6970b11" @@ -19153,12 +19260,19 @@ lodash._createassigner@^3.0.0: lodash._isiterateecall "^3.0.0" lodash.restparam "^3.0.0" +lodash._createcache@*: + version "3.1.2" + resolved "https://registry.yarnpkg.com/lodash._createcache/-/lodash._createcache-3.1.2.tgz#56d6a064017625e79ebca6b8018e17440bdcf093" + integrity sha512-ev5SP+iFpZOugyab/DEUQxUeZP5qyciVTlgQ1f4Vlw7VUcCD8fVnyIqVUEIaoFH9zjAqdgi69KiofzvVmda/ZQ== + dependencies: + lodash._getnative "^3.0.0" + lodash._createset@~4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/lodash._createset/-/lodash._createset-4.0.3.tgz#0f4659fbb09d75194fa9e2b88a6644d363c9fe26" integrity sha512-GTkC6YMprrJZCYU3zcqZj+jkXkrXzq3IPBcF/fIPpNEAB4hZEtXU8zp/RwKOvZl43NUmwDbyRk3+ZTbeRdEBXA== -lodash._getnative@^3.0.0: +lodash._getnative@*, lodash._getnative@^3.0.0: version "3.9.1" resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" integrity sha512-RrL9VxMEPyDMHOd9uFbvMe8X55X16/cGM5IgOKgRElQZutpX89iS6vwl64duTV1/16w5JY7tuFNXqoekmh1EmA== @@ -19371,7 +19485,7 @@ lodash.pick@^4.4.0: resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3" integrity sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q== -lodash.restparam@^3.0.0: +lodash.restparam@*, lodash.restparam@^3.0.0: version "3.6.1" resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" integrity sha512-L4/arjjuq4noiUJpt3yS6KIKDtJwNe2fIYgMqyYYKoeIfV1iEqvPwhCx23o+R9dzouGihDAPN1dTIRWa7zk8tw== @@ -23254,6 +23368,11 @@ regenerator-runtime@^0.11.0: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== +regenerator-runtime@^0.13.11: + version "0.13.11" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" + integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== + regenerator-runtime@^0.13.2, regenerator-runtime@^0.13.4, regenerator-runtime@^0.13.7: version "0.13.9" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" @@ -24482,6 +24601,13 @@ socks@~2.3.2: ip "1.1.5" smart-buffer "^4.1.0" +solid-js@^1.3.0: + version "1.6.11" + resolved "https://registry.yarnpkg.com/solid-js/-/solid-js-1.6.11.tgz#263a512bf94efd89245a77f58dc18c195302237f" + integrity sha512-JquQQHPArGq+i2PLURxJ99Pcz2/1docpbycSio/cKSA0SeI3z5zRjy0TNcH4NRYvbOLrcini+iovXwnexKabyw== + dependencies: + csstype "^3.1.0" + sort-object-keys@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/sort-object-keys/-/sort-object-keys-1.1.3.tgz#bff833fe85cab147b34742e45863453c1e190b45" From c30bc3a554d1af38b58c9a1e50c4671de20e8b62 Mon Sep 17 00:00:00 2001 From: Devon Anderson Date: Fri, 3 Mar 2023 12:43:47 -0500 Subject: [PATCH 011/193] =?UTF-8?q?chore:=20=F0=9F=A4=96=20create=20storag?= =?UTF-8?q?e=20bucket=20route=20(#95)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: πŸ€– create storage bucket route Create `storage-bucket` route and update `yaml` files βœ… Closes: ICU-8132 * refactor: πŸ’‘ removed future translations Removed translations tha will be coming for new storage-bucket form. βœ… Closes: ICU-8217 --- addons/core/translations/resources/en-us.yaml | 2 ++ ui/admin/app/router.js | 9 ++++++- .../routes/scopes/scope/storage-buckets.js | 5 ++++ .../scopes/scope/storage-buckets/index.js | 5 ++++ .../scopes/scope/storage-buckets/new.js | 26 +++++++++++++++++++ .../scope/storage-buckets/storage-bucket.js | 14 ++++++++++ .../storage-buckets/storage-bucket/index.js | 8 ++++++ .../scopes/scope/storage-buckets.hbs | 5 ++++ .../scopes/scope/storage-buckets/index.hbs | 4 +++ .../scopes/scope/storage-buckets/new.hbs | 6 +++++ .../scope/storage-buckets/storage-bucket.hbs | 9 +++++++ .../storage-buckets/storage-bucket/index.hbs | 4 +++ .../scopes/scope/storage-buckets-test.js | 5 ++++ .../scope/storage-buckets/index-test.js | 5 ++++ .../scopes/scope/storage-buckets/new-test.js | 16 ++++++++++++ .../storage-buckets/storage-bucket-test.js | 21 +++++++++++++++ .../storage-bucket/index-test.js | 21 +++++++++++++++ 17 files changed, 164 insertions(+), 1 deletion(-) create mode 100644 ui/admin/app/routes/scopes/scope/storage-buckets/new.js create mode 100644 ui/admin/app/routes/scopes/scope/storage-buckets/storage-bucket.js create mode 100644 ui/admin/app/routes/scopes/scope/storage-buckets/storage-bucket/index.js create mode 100644 ui/admin/app/templates/scopes/scope/storage-buckets/new.hbs create mode 100644 ui/admin/app/templates/scopes/scope/storage-buckets/storage-bucket.hbs create mode 100644 ui/admin/app/templates/scopes/scope/storage-buckets/storage-bucket/index.hbs create mode 100644 ui/admin/tests/unit/routes/scopes/scope/storage-buckets/new-test.js create mode 100644 ui/admin/tests/unit/routes/scopes/scope/storage-buckets/storage-bucket-test.js create mode 100644 ui/admin/tests/unit/routes/scopes/scope/storage-buckets/storage-bucket/index-test.js diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml index 425020e59..60fcc81d5 100644 --- a/addons/core/translations/resources/en-us.yaml +++ b/addons/core/translations/resources/en-us.yaml @@ -220,6 +220,8 @@ session-recording: storage-bucket: title: Storage Bucket title_plural: Storage Buckets + titles: + new: New Storage Bucket project: title: Project title_plural: Projects diff --git a/ui/admin/app/router.js b/ui/admin/app/router.js index 26ba1f57b..0187e2f03 100644 --- a/ui/admin/app/router.js +++ b/ui/admin/app/router.js @@ -148,7 +148,14 @@ Router.map(function () { } ); }); - this.route('storage-buckets', function () {}); + this.route('storage-buckets', function () { + this.route('new'); + this.route( + 'storage-bucket', + { path: ':storage_bucket_id' }, + function () {} + ); + }); }); }); diff --git a/ui/admin/app/routes/scopes/scope/storage-buckets.js b/ui/admin/app/routes/scopes/scope/storage-buckets.js index 9d17270e6..6c75be9b8 100644 --- a/ui/admin/app/routes/scopes/scope/storage-buckets.js +++ b/ui/admin/app/routes/scopes/scope/storage-buckets.js @@ -1,3 +1,8 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + import Route from '@ember/routing/route'; export default class ScopesScopeStorageBucketsRoute extends Route {} diff --git a/ui/admin/app/routes/scopes/scope/storage-buckets/index.js b/ui/admin/app/routes/scopes/scope/storage-buckets/index.js index e27e0a0dc..57bbf4b1f 100644 --- a/ui/admin/app/routes/scopes/scope/storage-buckets/index.js +++ b/ui/admin/app/routes/scopes/scope/storage-buckets/index.js @@ -1,3 +1,8 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + import Route from '@ember/routing/route'; export default class ScopesScopeStorageBucketsIndexRoute extends Route {} diff --git a/ui/admin/app/routes/scopes/scope/storage-buckets/new.js b/ui/admin/app/routes/scopes/scope/storage-buckets/new.js new file mode 100644 index 000000000..d318e1a66 --- /dev/null +++ b/ui/admin/app/routes/scopes/scope/storage-buckets/new.js @@ -0,0 +1,26 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import Route from '@ember/routing/route'; +import { inject as service } from '@ember/service'; + +export default class ScopesScopeStorageBucketsNewRoute extends Route { + // =services + + @service store; + + // =methods + + /** + * Creates a new unsaved storage bucket. + * @return {StorageBucket} + */ + model() { + const scopeModel = this.modelFor('scopes.scope'); + const record = this.store.createRecord('storage-bucket'); + record.scopeModel = scopeModel; + return record; + } +} diff --git a/ui/admin/app/routes/scopes/scope/storage-buckets/storage-bucket.js b/ui/admin/app/routes/scopes/scope/storage-buckets/storage-bucket.js new file mode 100644 index 000000000..8bf0c5ef4 --- /dev/null +++ b/ui/admin/app/routes/scopes/scope/storage-buckets/storage-bucket.js @@ -0,0 +1,14 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import Route from '@ember/routing/route'; + +export default class ScopesScopeStorageBucketsStorageBucketRoute extends Route { + model() { + return { + scope_id: 'sb_1234567890', + }; + } +} diff --git a/ui/admin/app/routes/scopes/scope/storage-buckets/storage-bucket/index.js b/ui/admin/app/routes/scopes/scope/storage-buckets/storage-bucket/index.js new file mode 100644 index 000000000..687ffc78a --- /dev/null +++ b/ui/admin/app/routes/scopes/scope/storage-buckets/storage-bucket/index.js @@ -0,0 +1,8 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import Route from '@ember/routing/route'; + +export default class ScopesScopeStorageBucketsStorageBucketIndexRoute extends Route {} diff --git a/ui/admin/app/templates/scopes/scope/storage-buckets.hbs b/ui/admin/app/templates/scopes/scope/storage-buckets.hbs index 5fda700a0..6067d7abe 100644 --- a/ui/admin/app/templates/scopes/scope/storage-buckets.hbs +++ b/ui/admin/app/templates/scopes/scope/storage-buckets.hbs @@ -1,3 +1,8 @@ +{{! + Copyright (c) HashiCorp, Inc. + SPDX-License-Identifier: MPL-2.0 +}} + {{page-title (t 'resources.storage-bucket.title_plural')}} {{outlet}} \ No newline at end of file diff --git a/ui/admin/app/templates/scopes/scope/storage-buckets/index.hbs b/ui/admin/app/templates/scopes/scope/storage-buckets/index.hbs index e69de29bb..3faf92ead 100644 --- a/ui/admin/app/templates/scopes/scope/storage-buckets/index.hbs +++ b/ui/admin/app/templates/scopes/scope/storage-buckets/index.hbs @@ -0,0 +1,4 @@ +{{! + Copyright (c) HashiCorp, Inc. + SPDX-License-Identifier: MPL-2.0 +}} \ No newline at end of file diff --git a/ui/admin/app/templates/scopes/scope/storage-buckets/new.hbs b/ui/admin/app/templates/scopes/scope/storage-buckets/new.hbs new file mode 100644 index 000000000..233691fac --- /dev/null +++ b/ui/admin/app/templates/scopes/scope/storage-buckets/new.hbs @@ -0,0 +1,6 @@ +{{! + Copyright (c) HashiCorp, Inc. + SPDX-License-Identifier: MPL-2.0 +}} + +{{page-title (t 'titles.new')}} \ No newline at end of file diff --git a/ui/admin/app/templates/scopes/scope/storage-buckets/storage-bucket.hbs b/ui/admin/app/templates/scopes/scope/storage-buckets/storage-bucket.hbs new file mode 100644 index 000000000..1d6ed5ba4 --- /dev/null +++ b/ui/admin/app/templates/scopes/scope/storage-buckets/storage-bucket.hbs @@ -0,0 +1,9 @@ +{{! + Copyright (c) HashiCorp, Inc. + SPDX-License-Identifier: MPL-2.0 +}} + +{{page-title @model.displayName}} + +

{{@model.scope_id}}

+{{outlet}} \ No newline at end of file diff --git a/ui/admin/app/templates/scopes/scope/storage-buckets/storage-bucket/index.hbs b/ui/admin/app/templates/scopes/scope/storage-buckets/storage-bucket/index.hbs new file mode 100644 index 000000000..3faf92ead --- /dev/null +++ b/ui/admin/app/templates/scopes/scope/storage-buckets/storage-bucket/index.hbs @@ -0,0 +1,4 @@ +{{! + Copyright (c) HashiCorp, Inc. + SPDX-License-Identifier: MPL-2.0 +}} \ No newline at end of file diff --git a/ui/admin/tests/unit/routes/scopes/scope/storage-buckets-test.js b/ui/admin/tests/unit/routes/scopes/scope/storage-buckets-test.js index 59c84d020..6f1795910 100644 --- a/ui/admin/tests/unit/routes/scopes/scope/storage-buckets-test.js +++ b/ui/admin/tests/unit/routes/scopes/scope/storage-buckets-test.js @@ -1,3 +1,8 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + import { module, test } from 'qunit'; import { setupTest } from 'admin/tests/helpers'; diff --git a/ui/admin/tests/unit/routes/scopes/scope/storage-buckets/index-test.js b/ui/admin/tests/unit/routes/scopes/scope/storage-buckets/index-test.js index 4c19c6e24..f8978d9f9 100644 --- a/ui/admin/tests/unit/routes/scopes/scope/storage-buckets/index-test.js +++ b/ui/admin/tests/unit/routes/scopes/scope/storage-buckets/index-test.js @@ -1,3 +1,8 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + import { module, test } from 'qunit'; import { setupTest } from 'admin/tests/helpers'; diff --git a/ui/admin/tests/unit/routes/scopes/scope/storage-buckets/new-test.js b/ui/admin/tests/unit/routes/scopes/scope/storage-buckets/new-test.js new file mode 100644 index 000000000..2c96c88cc --- /dev/null +++ b/ui/admin/tests/unit/routes/scopes/scope/storage-buckets/new-test.js @@ -0,0 +1,16 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import { module, test } from 'qunit'; +import { setupTest } from 'admin/tests/helpers'; + +module('Unit | Route | scopes/scope/storage-buckets/new', function (hooks) { + setupTest(hooks); + + test('it exists', function (assert) { + let route = this.owner.lookup('route:scopes/scope/storage-buckets/new'); + assert.ok(route); + }); +}); diff --git a/ui/admin/tests/unit/routes/scopes/scope/storage-buckets/storage-bucket-test.js b/ui/admin/tests/unit/routes/scopes/scope/storage-buckets/storage-bucket-test.js new file mode 100644 index 000000000..a4104dbf6 --- /dev/null +++ b/ui/admin/tests/unit/routes/scopes/scope/storage-buckets/storage-bucket-test.js @@ -0,0 +1,21 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import { module, test } from 'qunit'; +import { setupTest } from 'admin/tests/helpers'; + +module( + 'Unit | Route | scopes/scope/storage-buckets/storage-bucket', + function (hooks) { + setupTest(hooks); + + test('it exists', function (assert) { + let route = this.owner.lookup( + 'route:scopes/scope/storage-buckets/storage-bucket' + ); + assert.ok(route); + }); + } +); diff --git a/ui/admin/tests/unit/routes/scopes/scope/storage-buckets/storage-bucket/index-test.js b/ui/admin/tests/unit/routes/scopes/scope/storage-buckets/storage-bucket/index-test.js new file mode 100644 index 000000000..70bbcf915 --- /dev/null +++ b/ui/admin/tests/unit/routes/scopes/scope/storage-buckets/storage-bucket/index-test.js @@ -0,0 +1,21 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import { module, test } from 'qunit'; +import { setupTest } from 'admin/tests/helpers'; + +module( + 'Unit | Route | scopes/scope/storage-buckets/storage-bucket/index', + function (hooks) { + setupTest(hooks); + + test('it exists', function (assert) { + let route = this.owner.lookup( + 'route:scopes/scope/storage-buckets/storage-bucket/index' + ); + assert.ok(route); + }); + } +); From 4d62e67f2a1059d80bdb2d1b33d6117ecaf29c8c Mon Sep 17 00:00:00 2001 From: Zhihe Li Date: Fri, 3 Mar 2023 12:56:28 -0500 Subject: [PATCH 012/193] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20Add=20storage=20?= =?UTF-8?q?bucket=20models=20(#85)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 🎸 Add storage bucket models βœ… Closes: ICU-8076 --- .../addon/generated/models/storage-bucket.js | 88 +++++++++++++++++++ addons/api/addon/models/storage-bucket.js | 57 ++++++++++++ addons/api/app/models/storage-bucket.js | 1 + .../tests/unit/models/storage-bucket-test.js | 80 +++++++++++++++++ 4 files changed, 226 insertions(+) create mode 100644 addons/api/addon/generated/models/storage-bucket.js create mode 100644 addons/api/addon/models/storage-bucket.js create mode 100644 addons/api/app/models/storage-bucket.js create mode 100644 addons/api/tests/unit/models/storage-bucket-test.js diff --git a/addons/api/addon/generated/models/storage-bucket.js b/addons/api/addon/generated/models/storage-bucket.js new file mode 100644 index 000000000..6423d33ee --- /dev/null +++ b/addons/api/addon/generated/models/storage-bucket.js @@ -0,0 +1,88 @@ +import BaseModel from '../../models/base'; +import { attr } from '@ember-data/model'; + +/** + * A storage bucket is a resource that that represents a bucket in an external object store. + */ +export default class GeneratedStorageBucketModel extends BaseModel { + // =attributes + + @attr('string', { + description: 'The type of the resource, to help differentiate schemas', + }) + type; + + @attr({ + description: 'Plugin information for this resource.', + readOnly: true, + }) + plugin; + + @attr('string', { + description: 'Optional name for identification purposes.', + }) + name; + + @attr('string', { + description: 'Optional user-set description for identification purposes.', + }) + description; + + @attr('date', { + description: 'The time this resource was created\nOutput only.', + readOnly: true, + }) + created_time; + + @attr('date', { + description: 'The time this resource was last updated\nOutput only.', + readOnly: true, + }) + updated_time; + + @attr('number', { + description: 'Current version number of this resource.', + }) + version; + + @attr('string', { + description: 'The name of the bucket in the external object store.', + }) + bucket_name; + + @attr('string', { + description: + 'The base path where session recordings will be stored in the external object store.', + }) + bucket_prefix; + + @attr('string', { + description: + 'An expression used to filter the workers that have network access to a service that is hosting the external object store.', + }) + worker_filter; + + @attr('string', { + isNestedAttribute: true, + description: 'The AWS region to use.', + }) + region; + + @attr('string', { + readOnly: true, + isNestedAttribute: true, + }) + client_secret_hmac; + + @attr('string', { + isNestedSecret: true, + description: 'The AWS access key ID to use.', + }) + access_key_id; + + @attr('string', { + isNestedSecret: true, + description: 'The secret access key to use.', + }) + secret_access_key; +} diff --git a/addons/api/addon/models/storage-bucket.js b/addons/api/addon/models/storage-bucket.js new file mode 100644 index 000000000..768edfaed --- /dev/null +++ b/addons/api/addon/models/storage-bucket.js @@ -0,0 +1,57 @@ +import GeneratedStorageBucketModel from '../generated/models/storage-bucket'; + +export const TYPE_STORAGE_BUCKET_PLUGIN = 'plugin'; +export const TYPES_STORAGE_BUCKET = Object.freeze([TYPE_STORAGE_BUCKET_PLUGIN]); + +export const TYPE_STORAGE_BUCKET_PLUGIN_AWS_S3 = 'aws_s3'; +export const TYPES_STORAGE_BUCKET_PLUGIN = Object.freeze([ + TYPE_STORAGE_BUCKET_PLUGIN_AWS_S3, +]); + +export default class StorageBucketModel extends GeneratedStorageBucketModel { + /** + * True if the storage bucket is a plugin. + * @type {boolean} + */ + get isPlugin() { + return this.type === 'plugin'; + } + + /** + * True if the storage bucket is an unknown type. + * @type {boolean} + */ + get isUnknown() { + return ( + !TYPES_STORAGE_BUCKET.includes(this.type) || + (this.isPlugin && + !TYPES_STORAGE_BUCKET_PLUGIN.includes(this.plugin?.name)) + ); + } + + /** + * True if the storage bucket plugin type is AWS. + * @type {boolean} + */ + get isAWS() { + return this.compositeType === 'aws_s3'; + } + + /** + * If the storage bucket is a plugin return `plugin.name`, + * otherwise return the storage bucket type. + * @type {string} + */ + get compositeType() { + if (this.isUnknown) return 'unknown'; + return this.plugin.name; + } + + /** + * Sets `type` to `plugin` and `plugin.name` to the specified type. + */ + set compositeType(type) { + this.type = 'plugin'; + this.plugin = { name: type }; + } +} diff --git a/addons/api/app/models/storage-bucket.js b/addons/api/app/models/storage-bucket.js new file mode 100644 index 000000000..533d86097 --- /dev/null +++ b/addons/api/app/models/storage-bucket.js @@ -0,0 +1 @@ +export { default } from 'api/models/storage-bucket'; diff --git a/addons/api/tests/unit/models/storage-bucket-test.js b/addons/api/tests/unit/models/storage-bucket-test.js new file mode 100644 index 000000000..aff89dd3c --- /dev/null +++ b/addons/api/tests/unit/models/storage-bucket-test.js @@ -0,0 +1,80 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; +import { TYPE_STORAGE_BUCKET_PLUGIN_AWS_S3 } from 'api/models/storage-bucket'; + +module('Unit | Model | storage bucket', function (hooks) { + setupTest(hooks); + + test('it exists', function (assert) { + let store = this.owner.lookup('service:store'); + let model = store.createRecord('storage-bucket', {}); + assert.ok(model); + }); + + test('it has the isPlugin property and returns the expected values', async function (assert) { + assert.expect(1); + const store = this.owner.lookup('service:store'); + const modelPlugin = store.createRecord('storage-bucket', { + type: 'plugin', + plugin: { + name: TYPE_STORAGE_BUCKET_PLUGIN_AWS_S3, + }, + }); + assert.true(modelPlugin.isPlugin); + }); + + test('it has isUnknown property and returns the expected values', async function (assert) { + assert.expect(2); + const store = this.owner.lookup('service:store'); + const modelA = store.createRecord('storage-bucket', { + compositeType: TYPE_STORAGE_BUCKET_PLUGIN_AWS_S3, + }); + const modelB = store.createRecord('storage-bucket', { + compositeType: 'no-such-type', + }); + assert.false(modelA.isUnknown); + assert.true(modelB.isUnknown); + }); + + test('it has isAWS property and returns the expected values', async function (assert) { + assert.expect(2); + const store = this.owner.lookup('service:store'); + const modelAws = store.createRecord('storage-bucket', { + type: 'plugin', + plugin: { name: TYPE_STORAGE_BUCKET_PLUGIN_AWS_S3 }, + }); + const modelRandom = store.createRecord('storage-bucket', { + plugin: { name: 'random' }, + }); + assert.true(modelAws.isAWS); + assert.false(modelRandom.isAWS); + }); + + test('get compositeType returns expected values', async function (assert) { + assert.expect(2); + const store = this.owner.lookup('service:store'); + const modelA = store.createRecord('storage-bucket', { + type: 'plugin', + plugin: { name: TYPE_STORAGE_BUCKET_PLUGIN_AWS_S3 }, + }); + const modelB = store.createRecord('storage-bucket', { + type: 'plugin', + plugin: { name: 'no-such-type' }, + }); + assert.strictEqual(modelA.compositeType, TYPE_STORAGE_BUCKET_PLUGIN_AWS_S3); + assert.strictEqual(modelB.compositeType, 'unknown'); + }); + + test('set compositeType sets expected values', async function (assert) { + assert.expect(2); + const store = this.owner.lookup('service:store'); + const modelPlugin = store.createRecord('storage-bucket', { + compositeType: TYPE_STORAGE_BUCKET_PLUGIN_AWS_S3, + }); + assert.strictEqual(modelPlugin.type, 'plugin'); + assert.strictEqual( + modelPlugin.plugin.name, + TYPE_STORAGE_BUCKET_PLUGIN_AWS_S3 + ); + }); +}); From cd30f4e5ce54f510cb9da9c0122f4463254c810c Mon Sep 17 00:00:00 2001 From: Zhihe Li Date: Fri, 3 Mar 2023 13:27:14 -0500 Subject: [PATCH 013/193] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20Add=20mirage=20d?= =?UTF-8?q?ata=20for=20storage=20buckets=20(#91)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 🎸 Add mirage data for storage buckets βœ… Closes: ICU-8074 --- addons/api/mirage/config.js | 27 +++++++++- addons/api/mirage/factories/scope.js | 1 + addons/api/mirage/factories/storage-bucket.js | 51 +++++++++++++++++++ .../generated/factories/storage-bucket.js | 17 +++++++ addons/api/mirage/models/storage-bucket.js | 5 ++ addons/api/mirage/scenarios/default.js | 4 ++ .../api/mirage/serializers/storage-bucket.js | 4 ++ 7 files changed, 107 insertions(+), 2 deletions(-) create mode 100644 addons/api/mirage/factories/storage-bucket.js create mode 100644 addons/api/mirage/generated/factories/storage-bucket.js create mode 100644 addons/api/mirage/models/storage-bucket.js create mode 100644 addons/api/mirage/serializers/storage-bucket.js diff --git a/addons/api/mirage/config.js b/addons/api/mirage/config.js index cbf0b574f..cc8712d4b 100644 --- a/addons/api/mirage/config.js +++ b/addons/api/mirage/config.js @@ -634,8 +634,7 @@ function routes() { this.patch('/managed-groups/:id'); this.del('/managed-groups/:id'); - // worker - + // workers this.get( '/workers', ({ workers }, { queryParams: { scope_id: scopeId } }) => { @@ -656,6 +655,30 @@ function routes() { return workers.create(newWorker.attrs); }); + // storage-buckets + this.get( + '/storage-buckets', + ({ storageBuckets }, { queryParams: { scope_id: scopeId } }) => { + return storageBuckets.where({ scopeId }); + } + ); + this.get('/storage-buckets/:id'); + this.del('/storage-buckets/:id'); + this.patch('/storage-buckets/:id'); + this.post( + '/storage-buckets', + ({ storageBuckets }, { queryParams: { plugin_name } }) => { + const attrs = this.normalizedRequestAttrs(); + if (plugin_name) { + attrs.type = 'plugin'; + attrs.plugin = { + name: plugin_name, + }; + } + return storageBuckets.create(attrs); + } + ); + /* Uncomment the following line and the Response import above * Then change the response code to simulate error responses. * this.get('/scopes', () => new Response(505)); diff --git a/addons/api/mirage/factories/scope.js b/addons/api/mirage/factories/scope.js index 1a73738ab..eb8cf99bd 100644 --- a/addons/api/mirage/factories/scope.js +++ b/addons/api/mirage/factories/scope.js @@ -30,6 +30,7 @@ export default factory.extend({ 'credential-stores': ['create', 'list'], 'auth-methods': ['create', 'list'], 'host-catalogs': ['create', 'list'], + 'storage-buckets': ['create', 'list'], }; // Worker permissions only available on the global scope diff --git a/addons/api/mirage/factories/storage-bucket.js b/addons/api/mirage/factories/storage-bucket.js new file mode 100644 index 000000000..2145f6ed1 --- /dev/null +++ b/addons/api/mirage/factories/storage-bucket.js @@ -0,0 +1,51 @@ +import factory from '../generated/factories/storage-bucket'; +import permissions from '../helpers/permissions'; +import { faker } from '@faker-js/faker'; +import generateId from '../helpers/id'; +import { + TYPES_STORAGE_BUCKET as types, + TYPES_STORAGE_BUCKET_PLUGIN, + TYPE_STORAGE_BUCKET_PLUGIN_AWS_S3, +} from 'api/models/storage-bucket'; + +// Represents known plugin types, except "foobar" which models the possibility +// of receiving an _unknown_ type, which the UI must handle gracefully. +const pluginTypes = [...TYPES_STORAGE_BUCKET_PLUGIN, 'foobar']; + +export default factory.extend({ + id: () => generateId('sb_'), + + // Cycle through available types + type: (i) => types[i % types.length], + + authorized_actions: () => + permissions.authorizedActionsFor('storage-bucket') || [ + 'no-op', + 'read', + 'update', + 'delete', + ], + + plugin: function (i) { + if (this.type === 'plugin') { + return { + id: `plugin-id-${i}`, + name: pluginTypes[i % pluginTypes.length], + description: faker.random.words(), + }; + } + }, + + attributes() { + switch (this.plugin?.name) { + case TYPE_STORAGE_BUCKET_PLUGIN_AWS_S3: + return { + region: `us-${faker.address.cardinalDirection()}-${faker.datatype.number( + { + max: 9, + } + )}`, + }; + } + }, +}); diff --git a/addons/api/mirage/generated/factories/storage-bucket.js b/addons/api/mirage/generated/factories/storage-bucket.js new file mode 100644 index 000000000..f8346f8c6 --- /dev/null +++ b/addons/api/mirage/generated/factories/storage-bucket.js @@ -0,0 +1,17 @@ +import { Factory } from 'miragejs'; +import { faker } from '@faker-js/faker'; + +/** + * GeneratedStorageBucketModelFactory + */ +export default Factory.extend({ + type: 'plugin', + name: () => faker.random.words(), + description: () => faker.random.words(), + created_time: () => faker.date.recent(), + updated_time: () => faker.date.recent(), + version: () => faker.datatype.number(), + bucket_name: () => faker.internet.domainWord(), + bucket_prefix: () => faker.system.directoryPath(), + worker_filter: () => faker.random.words(), +}); diff --git a/addons/api/mirage/models/storage-bucket.js b/addons/api/mirage/models/storage-bucket.js new file mode 100644 index 000000000..27d40334d --- /dev/null +++ b/addons/api/mirage/models/storage-bucket.js @@ -0,0 +1,5 @@ +import { belongsTo } from 'miragejs'; +import Model from './base'; +export default Model.extend({ + scope: belongsTo(), +}); diff --git a/addons/api/mirage/scenarios/default.js b/addons/api/mirage/scenarios/default.js index 17a4fd90c..eb8531c2f 100644 --- a/addons/api/mirage/scenarios/default.js +++ b/addons/api/mirage/scenarios/default.js @@ -109,4 +109,8 @@ export default function (server) { // Workers server.createList('worker', 3, { scope: globalScope }); + + // Session Recordings and Storage Buckets + server.createList('storage-bucket', 3, { scope: globalScope }); + server.createList('storage-bucket', 2, { scope: orgScope }); } diff --git a/addons/api/mirage/serializers/storage-bucket.js b/addons/api/mirage/serializers/storage-bucket.js new file mode 100644 index 000000000..7a5bc48df --- /dev/null +++ b/addons/api/mirage/serializers/storage-bucket.js @@ -0,0 +1,4 @@ +import ApplicationSerializer from './application'; +export default ApplicationSerializer.extend({ + modelName: 'storage-bucket', +}); From e735e6a48740678fa3d907eac6384d1e7bffeb01 Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Date: Fri, 3 Mar 2023 10:57:15 -0800 Subject: [PATCH 014/193] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Outdated=20yarn.l?= =?UTF-8?q?ock?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yarn.lock | 27 +++++---------------------- 1 file changed, 5 insertions(+), 22 deletions(-) diff --git a/yarn.lock b/yarn.lock index 75b1d2ce9..094a5753d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11905,7 +11905,7 @@ debug@^3.0.0, debug@^3.0.1, debug@^3.1.0, debug@^3.1.1, debug@^3.2.7: dependencies: ms "^2.1.1" -debuglog@*, debuglog@^1.0.1: +debuglog@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" integrity sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI= @@ -17097,7 +17097,7 @@ import-local@^3.0.2: pkg-dir "^4.2.0" resolve-cwd "^3.0.0" -imurmurhash@*, imurmurhash@^0.1.4: +imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= @@ -19228,11 +19228,6 @@ lodash._baseflatten@^3.0.0: lodash.isarguments "^3.0.0" lodash.isarray "^3.0.0" -lodash._baseindexof@*: - version "3.1.0" - resolved "https://registry.yarnpkg.com/lodash._baseindexof/-/lodash._baseindexof-3.1.0.tgz#fe52b53a1c6761e42618d654e4a25789ed61822c" - integrity sha512-bSYo8Pc/f0qAkr8fPJydpJjtrHiSynYfYBjtANIgXv5xEf1WlTC63dIDlgu0s9dmTvzRu1+JJTxcIAHe+sH0FQ== - lodash._baseuniq@~4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash._baseuniq/-/lodash._baseuniq-4.6.0.tgz#0ebb44e456814af7905c6212fa2c9b2d51b841e8" @@ -19241,16 +19236,11 @@ lodash._baseuniq@~4.6.0: lodash._createset "~4.0.0" lodash._root "~3.0.0" -lodash._bindcallback@*, lodash._bindcallback@^3.0.0: +lodash._bindcallback@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz#e531c27644cf8b57a99e17ed95b35c748789392e" integrity sha512-2wlI0JRAGX8WEf4Gm1p/mv/SZ+jLijpj0jyaE/AXeuQphzCgD8ZQW4oSpoN8JAopujOFGU3KMuq7qfHBWlGpjQ== -lodash._cacheindexof@*: - version "3.0.2" - resolved "https://registry.yarnpkg.com/lodash._cacheindexof/-/lodash._cacheindexof-3.0.2.tgz#3dc69ac82498d2ee5e3ce56091bafd2adc7bde92" - integrity sha512-S8dUjWr7SUT/X6TBIQ/OYoCHo1Stu1ZRy6uMUSKqzFnZp5G5RyQizSm6kvxD2Ewyy6AVfMg4AToeZzKfF99T5w== - lodash._createassigner@^3.0.0: version "3.1.1" resolved "https://registry.yarnpkg.com/lodash._createassigner/-/lodash._createassigner-3.1.1.tgz#838a5bae2fdaca63ac22dee8e19fa4e6d6970b11" @@ -19260,19 +19250,12 @@ lodash._createassigner@^3.0.0: lodash._isiterateecall "^3.0.0" lodash.restparam "^3.0.0" -lodash._createcache@*: - version "3.1.2" - resolved "https://registry.yarnpkg.com/lodash._createcache/-/lodash._createcache-3.1.2.tgz#56d6a064017625e79ebca6b8018e17440bdcf093" - integrity sha512-ev5SP+iFpZOugyab/DEUQxUeZP5qyciVTlgQ1f4Vlw7VUcCD8fVnyIqVUEIaoFH9zjAqdgi69KiofzvVmda/ZQ== - dependencies: - lodash._getnative "^3.0.0" - lodash._createset@~4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/lodash._createset/-/lodash._createset-4.0.3.tgz#0f4659fbb09d75194fa9e2b88a6644d363c9fe26" integrity sha512-GTkC6YMprrJZCYU3zcqZj+jkXkrXzq3IPBcF/fIPpNEAB4hZEtXU8zp/RwKOvZl43NUmwDbyRk3+ZTbeRdEBXA== -lodash._getnative@*, lodash._getnative@^3.0.0: +lodash._getnative@^3.0.0: version "3.9.1" resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" integrity sha512-RrL9VxMEPyDMHOd9uFbvMe8X55X16/cGM5IgOKgRElQZutpX89iS6vwl64duTV1/16w5JY7tuFNXqoekmh1EmA== @@ -19485,7 +19468,7 @@ lodash.pick@^4.4.0: resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3" integrity sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q== -lodash.restparam@*, lodash.restparam@^3.0.0: +lodash.restparam@^3.0.0: version "3.6.1" resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" integrity sha512-L4/arjjuq4noiUJpt3yS6KIKDtJwNe2fIYgMqyYYKoeIfV1iEqvPwhCx23o+R9dzouGihDAPN1dTIRWa7zk8tw== From 6d6b4bee05bcc8a0ec6db1b3f549b606b982f907 Mon Sep 17 00:00:00 2001 From: lisbet-alvarez <107949262+lisbet-alvarez@users.noreply.github.com> Date: Fri, 3 Mar 2023 12:03:34 -0800 Subject: [PATCH 015/193] =?UTF-8?q?chore:=20=F0=9F=A4=96=20add=20storage?= =?UTF-8?q?=20bucket=20link=20on=20left=20sidebar=20(#94)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: πŸ€– update branch * chore: πŸ€– add storage bucket link to org scope as well * refactor: πŸ’‘ remove link form org scope βœ… Closes: ICU-8222 --- ui/admin/app/templates/scopes/scope.hbs | 31 ++++++++++++++----------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/ui/admin/app/templates/scopes/scope.hbs b/ui/admin/app/templates/scopes/scope.hbs index 380ea8fe9..864676e01 100644 --- a/ui/admin/app/templates/scopes/scope.hbs +++ b/ui/admin/app/templates/scopes/scope.hbs @@ -26,23 +26,28 @@ {{t 'resources.org.title_plural'}} - - {{#if - (and - (can 'navigate worker' @model collection='workers') - (feature-flag 'byow') - ) - }} - + {{! TODO: Check can abilities }} + {{#if (feature-flag 'session-recording')}} + + + {{t 'resources.storage-bucket.title_plural'}} + + {{/if}} + {{#if + (and + (can 'navigate worker' @model collection='workers') + (feature-flag 'byow') + ) + }} {{t 'resources.worker.title_plural'}} - - {{/if}} + {{/if}} + {{/if}} {{#if @model.isOrg}} From a3502b489e06a0e3f0cf187ed8422ce34a965ed4 Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Date: Fri, 3 Mar 2023 13:16:27 -0800 Subject: [PATCH 016/193] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20Sidebar=20naviga?= =?UTF-8?q?tion=20to=20Session=20recordings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- addons/core/translations/resources/en-us.yaml | 4 ++-- ui/admin/app/templates/scopes/scope.hbs | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml index 60fcc81d5..8ff213264 100644 --- a/addons/core/translations/resources/en-us.yaml +++ b/addons/core/translations/resources/en-us.yaml @@ -212,8 +212,8 @@ org: actions: delete: Delete Org session-recording: - title: Recorded Session - title_plural: Recorded Sessions + title: Session Recording + title_plural: Session Recordings channel: title: Channel title_plural: Channels diff --git a/ui/admin/app/templates/scopes/scope.hbs b/ui/admin/app/templates/scopes/scope.hbs index 864676e01..7d9a2836d 100644 --- a/ui/admin/app/templates/scopes/scope.hbs +++ b/ui/admin/app/templates/scopes/scope.hbs @@ -28,6 +28,10 @@ {{! TODO: Check can abilities }} {{#if (feature-flag 'session-recording')}} + + + {{t 'resources.session-recording.title_plural'}} + Date: Tue, 7 Mar 2023 11:04:33 -0600 Subject: [PATCH 017/193] =?UTF-8?q?refactor:=20=F0=9F=92=A1=20manually=20b?= =?UTF-8?q?uild=20ascii=20cast=20data=20for=20player=20(#104)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../channels-by-connection/channel.js | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.js b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.js index 0db1b6ae4..2765d6c69 100644 --- a/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.js +++ b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.js @@ -2,8 +2,24 @@ import Route from '@ember/routing/route'; export default class ScopesScopeSessionRecordingsSessionRecordingChannelsByConnectionChannelRoute extends Route { async model() { - const response = await fetch('/session.cast'); - const asciicast = await response.text(); + // building ascii cast here to make player availabe until API is ready + const castConfig = { + version: 2, + width: 124, + height: 36, + timestamp: 1670352594, + env: { SHELL: '/bin/zsh', TERM: 'xterm-256color' }, + }; + const asciicast = `${JSON.stringify(castConfig)} +[2.676444, "o", "y"] +[2.788653, "o", "a"] +[2.868652, "o", "r"] +[3.001764, "o", "n"] +[3.167636, "o", " "] +[3.313668, "o", "t"] +[3.460527, "o", "e"] +[3.561983, "o", "s"] +[3.63678, "o", "t"]`; return { scope_id: 'srcc_1234567890', asciicast: asciicast, From 449ea383c9b195cfadcb3f1588f10b6aa8a1fa5c Mon Sep 17 00:00:00 2001 From: Cameron Perera Date: Tue, 7 Mar 2023 11:04:51 -0600 Subject: [PATCH 018/193] Icu 8329 create custom boundary wrapper for ember asciinema player (#103) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: πŸ’‘ fix broken page title translations * feat: 🎸 create SessionRecording::Player component βœ… Closes: ICU-8329 --- .../session-recording/player/index.hbs | 12 +++++++ .../channels-by-connection.hbs | 2 +- .../channels-by-connection/channel.hbs | 6 ++-- .../session-recording/player-test.js | 34 +++++++++++++++++++ 4 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 ui/admin/app/components/session-recording/player/index.hbs create mode 100644 ui/admin/tests/integration/components/session-recording/player-test.js diff --git a/ui/admin/app/components/session-recording/player/index.hbs b/ui/admin/app/components/session-recording/player/index.hbs new file mode 100644 index 000000000..377faca68 --- /dev/null +++ b/ui/admin/app/components/session-recording/player/index.hbs @@ -0,0 +1,12 @@ +
+
+ +
+
+ +
+
\ No newline at end of file diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection.hbs index 708976b2e..5915f218c 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection.hbs @@ -1,3 +1,3 @@ -{{page-title (t 'resources.session-recordings.channel.title_plural')}} +{{page-title (t 'resources.session-recording.channel.title_plural')}} {{outlet}} \ No newline at end of file diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs index 0aa78b6e8..22b74e153 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs @@ -1,7 +1,5 @@ -{{page-title (t 'resources.session-recordings.channel.title')}} +{{page-title (t 'resources.session-recording.channel.title')}}

{{@model.scope_id}}

-
- -
+ {{outlet}} \ No newline at end of file diff --git a/ui/admin/tests/integration/components/session-recording/player-test.js b/ui/admin/tests/integration/components/session-recording/player-test.js new file mode 100644 index 000000000..fc93a81f5 --- /dev/null +++ b/ui/admin/tests/integration/components/session-recording/player-test.js @@ -0,0 +1,34 @@ +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'admin/tests/helpers'; +import { render } from '@ember/test-helpers'; +import { hbs } from 'ember-cli-htmlbars'; + +module('Integration | Component | session-recording/player', function (hooks) { + setupRenderingTest(hooks); + + test('it renders', async function (assert) { + const castConfig = { + version: 2, + width: 124, + height: 36, + timestamp: 1670352594, + env: { SHELL: '/bin/zsh', TERM: 'xterm-256color' }, + }; + this.cast = `${JSON.stringify(castConfig)} +[2.676444, "o", "y"] +[2.788653, "o", "a"] +[2.868652, "o", "r"] +[3.001764, "o", "n"] +[3.167636, "o", " "] +[3.313668, "o", "t"] +[3.460527, "o", "e"] +[3.561983, "o", "s"] +[3.63678, "o", "t"]`; + + await render(hbs` + + `); + + assert.dom(this.element).hasText('Back to channels --:----:--'); + }); +}); From b91b7ef4bbca17ce4db32f3499bec978e7507efc Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Corvo Date: Tue, 7 Mar 2023 10:55:52 -0800 Subject: [PATCH 019/193] Add navigation to Session Recordings (#105) * Add navigation from Session recordings to session recording (detail) * Add navigation from session recording (detail) to a specific channel detail * Comment model code --- addons/core/translations/resources/en-us.yaml | 2 ++ .../routes/scopes/scope/session-recordings.js | 3 +++ .../session-recordings/session-recording.js | 3 ++- .../scopes/scope/session-recordings.hbs | 1 - .../scopes/scope/session-recordings/index.hbs | 14 ++++++++++++++ .../session-recordings/session-recording.hbs | 2 -- .../session-recording/index.hbs | 19 +++++++++++++++++++ 7 files changed, 40 insertions(+), 4 deletions(-) diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml index 8ff213264..16326b2f2 100644 --- a/addons/core/translations/resources/en-us.yaml +++ b/addons/core/translations/resources/en-us.yaml @@ -217,6 +217,8 @@ session-recording: channel: title: Channel title_plural: Channels + session: + title: Session Playback storage-bucket: title: Storage Bucket title_plural: Storage Buckets diff --git a/ui/admin/app/routes/scopes/scope/session-recordings.js b/ui/admin/app/routes/scopes/scope/session-recordings.js index 4cca21156..efffa07f1 100644 --- a/ui/admin/app/routes/scopes/scope/session-recordings.js +++ b/ui/admin/app/routes/scopes/scope/session-recordings.js @@ -29,6 +29,9 @@ export default class ScopesScopeSessionRecordingsRoute extends Route { // if (this.can.can('list session-recording', scope, { collection: 'session-recordings' })) { // return this.store.query('session-recording', { scope_id }); // } + return { + session_recording_id: 'sr_1234567890', + }; } // =actions diff --git a/ui/admin/app/routes/scopes/scope/session-recordings/session-recording.js b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording.js index 0c76fa6df..eda72d65e 100644 --- a/ui/admin/app/routes/scopes/scope/session-recordings/session-recording.js +++ b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording.js @@ -5,7 +5,8 @@ export default class ScopesScopeSessionRecordingsSessionRecordingRoute extends R // =methods model() { return { - scope_id: 'sr_1234567890', + session_recording_id: 'sr_1234567890', + channel_connection_id: 'srcc_1234567890', }; } } diff --git a/ui/admin/app/templates/scopes/scope/session-recordings.hbs b/ui/admin/app/templates/scopes/scope/session-recordings.hbs index fde0c392e..8a94562e7 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings.hbs @@ -1,3 +1,2 @@ {{page-title (t 'resources.session-recording.title_plural')}} - {{outlet}} \ No newline at end of file diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs index e69de29bb..1ce0230e6 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs @@ -0,0 +1,14 @@ + + +

{{t 'resources.session-recording.title_plural'}}

+
+ + + + {{@model.session_recording_id}} + + +
\ No newline at end of file diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording.hbs index 4c1ce9936..f6557cda4 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording.hbs @@ -1,4 +1,2 @@ {{page-title @model.displayName}} - -

{{@model.scope_id}}

{{outlet}} \ No newline at end of file diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs index e69de29bb..981e709ba 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs @@ -0,0 +1,19 @@ + + +

{{t 'resources.session-recording.session.title'}}

+
+ + +

{{t 'resources.session-recording.title'}} + {{@model.session_recording_id}}

+

{{t 'resources.session-recording.channel.title'}} + {{@model.channel_connection_id}}

+ + + {{@model.channel_connection_id}} + +
+
\ No newline at end of file From b9cf61932b41b37c36c03da658d451aed11a1f86 Mon Sep 17 00:00:00 2001 From: Zhihe Li Date: Tue, 7 Mar 2023 16:38:41 -0500 Subject: [PATCH 020/193] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20Add=20session=20?= =?UTF-8?q?recording=20models=20(#100)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 🎸 Add session recording models βœ… Closes: ICU-8075 --- addons/api/addon/generated/models/channel.js | 53 ++++++++++++ .../api/addon/generated/models/connection.js | 47 +++++++++++ .../api/addon/generated/models/recording.js | 83 +++++++++++++++++++ addons/api/addon/models/channel.js | 25 ++++++ addons/api/addon/models/connection.js | 7 ++ addons/api/addon/models/recording.js | 25 ++++++ addons/api/app/models/channel.js | 1 + addons/api/app/models/connection.js | 1 + addons/api/app/models/recording.js | 1 + addons/api/tests/unit/models/channel-test.js | 39 +++++++++ .../api/tests/unit/models/connection-test.js | 23 +++++ .../api/tests/unit/models/recording-test.js | 53 ++++++++++++ 12 files changed, 358 insertions(+) create mode 100644 addons/api/addon/generated/models/channel.js create mode 100644 addons/api/addon/generated/models/connection.js create mode 100644 addons/api/addon/generated/models/recording.js create mode 100644 addons/api/addon/models/channel.js create mode 100644 addons/api/addon/models/connection.js create mode 100644 addons/api/addon/models/recording.js create mode 100644 addons/api/app/models/channel.js create mode 100644 addons/api/app/models/connection.js create mode 100644 addons/api/app/models/recording.js create mode 100644 addons/api/tests/unit/models/channel-test.js create mode 100644 addons/api/tests/unit/models/connection-test.js create mode 100644 addons/api/tests/unit/models/recording-test.js diff --git a/addons/api/addon/generated/models/channel.js b/addons/api/addon/generated/models/channel.js new file mode 100644 index 000000000..6f9a68b71 --- /dev/null +++ b/addons/api/addon/generated/models/channel.js @@ -0,0 +1,53 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import BaseModel from '../../models/base'; +import { attr } from '@ember-data/model'; + +/** + * A channel contains data for a single channel within a connection. + */ +export default class GeneratedChannelModel extends BaseModel { + // =attributes + + @attr('string', { + description: 'The type of the resource, to help differentiate schemas', + readOnly: true, + }) + type; + + @attr('number', { + description: + 'The total number of bytes uploaded from the client in this Channel.', + readOnly: true, + }) + bytes_up; + + @attr('number', { + description: + 'The total number of bytes downloaded to the client in this Channel.', + readOnly: true, + }) + bytes_down; + + @attr('number', { + description: + 'The total number of errors that occurred during the use of this Channel.', + readOnly: true, + }) + errors; + + @attr('date', { + description: 'The time the Channel started.', + readOnly: true, + }) + started_time; + + @attr('date', { + description: 'The time the Channel finished.', + readOnly: true, + }) + finished_time; +} diff --git a/addons/api/addon/generated/models/connection.js b/addons/api/addon/generated/models/connection.js new file mode 100644 index 000000000..b0d28d7f2 --- /dev/null +++ b/addons/api/addon/generated/models/connection.js @@ -0,0 +1,47 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import BaseModel from '../../models/base'; +import { attr } from '@ember-data/model'; + +/** + * A connection contains data for a boundary connection within a session. + */ +export default class GeneratedConnectionModel extends BaseModel { + // =attributes + + @attr('number', { + description: + 'The total number of bytes uploaded from the client in this Connection.', + readOnly: true, + }) + bytes_up; + + @attr('number', { + description: + 'The total number of bytes downloaded to the client in this Connection.', + readOnly: true, + }) + bytes_down; + + @attr('number', { + description: + 'The total number of errors that occurred during the use of this Connection.', + readOnly: true, + }) + errors; + + @attr('date', { + description: 'The time the Connection started.', + readOnly: true, + }) + started_time; + + @attr('date', { + description: 'The time the Connection finished.', + readOnly: true, + }) + finished_time; +} diff --git a/addons/api/addon/generated/models/recording.js b/addons/api/addon/generated/models/recording.js new file mode 100644 index 000000000..4853894e6 --- /dev/null +++ b/addons/api/addon/generated/models/recording.js @@ -0,0 +1,83 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import BaseModel from '../../models/base'; +import { attr } from '@ember-data/model'; + +/** + * A recording contains all data related to session recordings + */ +export default class GeneratedRecordingModel extends BaseModel { + // =attributes + + @attr('string', { + description: 'The type of the resource, to help differentiate schemas.', + readOnly: true, + }) + type; + + @attr({ + description: 'The user who created the session.', + readOnly: true, + }) + user; + + @attr({ + description: 'The target the session connected to.', + readOnly: true, + }) + target; + + @attr('string', { + description: 'The ID of the Session which this Session Recording recorded.', + readOnly: true, + }) + session_id; + + @attr('number', { + description: + 'The total number of bytes uploaded from the client in the Session.', + readOnly: true, + }) + bytes_up; + + @attr('number', { + description: + 'The total number of bytes downloaded to the client in the Session.', + readOnly: true, + }) + bytes_down; + + @attr('number', { + description: + 'The total number of errors that occurred during the use of the Session.', + readOnly: true, + }) + errors; + + @attr('date', { + description: 'The time the Session started.', + readOnly: true, + }) + started_time; + + @attr('date', { + description: 'The time the Session finished.', + readOnly: true, + }) + finished_time; + + @attr('date', { + description: 'The time the Session recording was last updated.', + readOnly: true, + }) + updated_time; + + @attr('date', { + description: 'The time that the Session recording will be deleted.', + readOnly: true, + }) + delete_on; +} diff --git a/addons/api/addon/models/channel.js b/addons/api/addon/models/channel.js new file mode 100644 index 000000000..f0e776d8e --- /dev/null +++ b/addons/api/addon/models/channel.js @@ -0,0 +1,25 @@ +import GeneratedChannelModel from '../generated/models/channel'; +import { belongsTo } from '@ember-data/model'; + +export const TYPE_CHANNEL_SESSION = 'session'; +export const TYPES_CHANNEL = Object.freeze([TYPE_CHANNEL_SESSION]); + +export default class ChannelModel extends GeneratedChannelModel { + @belongsTo('connection') connection; + + /** + * True if the channel type is `session`. + * @type {boolean} + */ + get isSession() { + return this.type === TYPE_CHANNEL_SESSION; + } + + /** + * True if the channel is an unknown type. + * @type {boolean} + */ + get isUnknown() { + return !TYPES_CHANNEL.includes(this.type); + } +} diff --git a/addons/api/addon/models/connection.js b/addons/api/addon/models/connection.js new file mode 100644 index 000000000..482e85b4d --- /dev/null +++ b/addons/api/addon/models/connection.js @@ -0,0 +1,7 @@ +import GeneratedConnectionModel from '../generated/models/connection'; +import { belongsTo, hasMany } from '@ember-data/model'; + +export default class ConnectionModel extends GeneratedConnectionModel { + @belongsTo('recording') recording; + @hasMany('channel') channels; +} diff --git a/addons/api/addon/models/recording.js b/addons/api/addon/models/recording.js new file mode 100644 index 000000000..bea1ee92d --- /dev/null +++ b/addons/api/addon/models/recording.js @@ -0,0 +1,25 @@ +import GeneratedRecordingModel from '../generated/models/recording'; +import { hasMany } from '@ember-data/model'; + +export const TYPE_RECORDING_SSH = 'ssh'; +export const TYPES_RECORDING = Object.freeze([TYPE_RECORDING_SSH]); + +export default class RecordingModel extends GeneratedRecordingModel { + @hasMany('connection') connections; + + /** + * True if the recording type is `ssh`. + * @type {boolean} + */ + get isSSH() { + return this.type === TYPE_RECORDING_SSH; + } + + /** + * True if the recording is an unknown type. + * @type {boolean} + */ + get isUnknown() { + return !TYPES_RECORDING.includes(this.type); + } +} diff --git a/addons/api/app/models/channel.js b/addons/api/app/models/channel.js new file mode 100644 index 000000000..83fa2e823 --- /dev/null +++ b/addons/api/app/models/channel.js @@ -0,0 +1 @@ +export { default } from 'api/models/channel'; diff --git a/addons/api/app/models/connection.js b/addons/api/app/models/connection.js new file mode 100644 index 000000000..17c9eb2ac --- /dev/null +++ b/addons/api/app/models/connection.js @@ -0,0 +1 @@ +export { default } from 'api/models/connection'; diff --git a/addons/api/app/models/recording.js b/addons/api/app/models/recording.js new file mode 100644 index 000000000..bdcbf74be --- /dev/null +++ b/addons/api/app/models/recording.js @@ -0,0 +1 @@ +export { default } from 'api/models/recording'; diff --git a/addons/api/tests/unit/models/channel-test.js b/addons/api/tests/unit/models/channel-test.js new file mode 100644 index 000000000..7447e0eb6 --- /dev/null +++ b/addons/api/tests/unit/models/channel-test.js @@ -0,0 +1,39 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; +import { TYPE_CHANNEL_SESSION } from 'api/models/channel'; + +module('Unit | Model | channel', function (hooks) { + setupTest(hooks); + + test('it exists', function (assert) { + let store = this.owner.lookup('service:store'); + let model = store.createRecord('channel', {}); + assert.ok(model); + }); + + test('it has isUnknown property and returns the expected values', async function (assert) { + assert.expect(2); + const store = this.owner.lookup('service:store'); + const modelA = store.createRecord('channel', { + type: TYPE_CHANNEL_SESSION, + }); + const modelB = store.createRecord('channel', { + type: 'no-such-type', + }); + assert.false(modelA.isUnknown); + assert.true(modelB.isUnknown); + }); + + test('it has isSession property and returns the expected values', async function (assert) { + assert.expect(2); + const store = this.owner.lookup('service:store'); + const modelA = store.createRecord('channel', { + type: TYPE_CHANNEL_SESSION, + }); + const modelB = store.createRecord('channel', { + type: 'random', + }); + assert.true(modelA.isSession); + assert.false(modelB.isSession); + }); +}); diff --git a/addons/api/tests/unit/models/connection-test.js b/addons/api/tests/unit/models/connection-test.js new file mode 100644 index 000000000..e6d50eaa9 --- /dev/null +++ b/addons/api/tests/unit/models/connection-test.js @@ -0,0 +1,23 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Model | connection', function (hooks) { + setupTest(hooks); + + test('it exists', function (assert) { + let store = this.owner.lookup('service:store'); + let model = store.createRecord('connection', {}); + assert.ok(model); + }); + + test('it has channels as a relationship', async function (assert) { + assert.expect(1); + const store = this.owner.lookup('service:store'); + const model = store.createRecord('connection', { + channels: [store.createRecord('channel')], + }); + + const channels = await model.channels; + assert.strictEqual(channels.length, 1); + }); +}); diff --git a/addons/api/tests/unit/models/recording-test.js b/addons/api/tests/unit/models/recording-test.js new file mode 100644 index 000000000..096954c8b --- /dev/null +++ b/addons/api/tests/unit/models/recording-test.js @@ -0,0 +1,53 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; +import { TYPE_RECORDING_SSH } from 'api/models/recording'; +import setupMirage from 'ember-cli-mirage/test-support/setup-mirage'; + +module('Unit | Model | recording', function (hooks) { + setupTest(hooks); + setupMirage(hooks); + + test('it exists', function (assert) { + let store = this.owner.lookup('service:store'); + let model = store.createRecord('recording', {}); + assert.ok(model); + }); + + test('it has isUnknown property and returns the expected values', async function (assert) { + assert.expect(2); + const store = this.owner.lookup('service:store'); + const modelA = store.createRecord('recording', { + type: TYPE_RECORDING_SSH, + }); + const modelB = store.createRecord('recording', { + type: 'no-such-type', + }); + assert.false(modelA.isUnknown); + assert.true(modelB.isUnknown); + }); + + test('it has isSSH property and returns the expected values', async function (assert) { + assert.expect(2); + const store = this.owner.lookup('service:store'); + const modelA = store.createRecord('recording', { + type: TYPE_RECORDING_SSH, + }); + const modelB = store.createRecord('recording', { + type: 'random', + }); + assert.true(modelA.isSSH); + assert.false(modelB.isSSH); + }); + + test('it has connections as a relationship', async function (assert) { + assert.expect(1); + const store = this.owner.lookup('service:store'); + const model = store.createRecord('recording', { + type: TYPE_RECORDING_SSH, + connections: [store.createRecord('connection')], + }); + + const connections = await model.connections; + assert.strictEqual(connections.length, 1); + }); +}); From ef55d71a55dfa6e5d694e4dfd965a2d7f567eaa8 Mon Sep 17 00:00:00 2001 From: Cameron Perera Date: Tue, 7 Mar 2023 16:41:33 -0600 Subject: [PATCH 021/193] =?UTF-8?q?refactor:=20=F0=9F=92=A1=20allow=20pass?= =?UTF-8?q?through=20in=20mirage=20for=20asciicast=20data=20(#108)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- addons/api/mirage/config.js | 1 + .../channels-by-connection/channel.js | 21 +++---------------- 2 files changed, 4 insertions(+), 18 deletions(-) diff --git a/addons/api/mirage/config.js b/addons/api/mirage/config.js index cc8712d4b..d6b519784 100644 --- a/addons/api/mirage/config.js +++ b/addons/api/mirage/config.js @@ -33,6 +33,7 @@ export default function (mirageConfig) { function routes() { initializeMockIPC(this, environmentConfig); + this.passthrough(); // make this `http://localhost:8080`, for example, if your API is on a different server // this.urlPrefix = ''; // make this `/api`, for example, if your API is namespaced diff --git a/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.js b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.js index 2765d6c69..494ee45e6 100644 --- a/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.js +++ b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.js @@ -2,24 +2,9 @@ import Route from '@ember/routing/route'; export default class ScopesScopeSessionRecordingsSessionRecordingChannelsByConnectionChannelRoute extends Route { async model() { - // building ascii cast here to make player availabe until API is ready - const castConfig = { - version: 2, - width: 124, - height: 36, - timestamp: 1670352594, - env: { SHELL: '/bin/zsh', TERM: 'xterm-256color' }, - }; - const asciicast = `${JSON.stringify(castConfig)} -[2.676444, "o", "y"] -[2.788653, "o", "a"] -[2.868652, "o", "r"] -[3.001764, "o", "n"] -[3.167636, "o", " "] -[3.313668, "o", "t"] -[3.460527, "o", "e"] -[3.561983, "o", "s"] -[3.63678, "o", "t"]`; + const response = await fetch('/session.cast'); + const asciicast = await response.text(); + return { scope_id: 'srcc_1234567890', asciicast: asciicast, From 94c302739202f20dbc98a81cc8b8df3b2fec4013 Mon Sep 17 00:00:00 2001 From: lisbet-alvarez <107949262+lisbet-alvarez@users.noreply.github.com> Date: Wed, 8 Mar 2023 08:42:20 -0800 Subject: [PATCH 022/193] =?UTF-8?q?test:=20=F0=9F=92=8D=20acceptance=20tes?= =?UTF-8?q?ts=20for=20navigation=20link=20(#102)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * test: πŸ’ acceptance tests for navigation link βœ… Closes: ICU-8224 --- ui/admin/app/templates/scopes/scope.hbs | 16 +- .../acceptance/storage-buckets/list-test.js | 139 ++++++++++++++++++ .../acceptance/storage-buckets/read-test.js | 57 +++++++ 3 files changed, 205 insertions(+), 7 deletions(-) create mode 100644 ui/admin/tests/acceptance/storage-buckets/list-test.js create mode 100644 ui/admin/tests/acceptance/storage-buckets/read-test.js diff --git a/ui/admin/app/templates/scopes/scope.hbs b/ui/admin/app/templates/scopes/scope.hbs index 7d9a2836d..22be84374 100644 --- a/ui/admin/app/templates/scopes/scope.hbs +++ b/ui/admin/app/templates/scopes/scope.hbs @@ -32,13 +32,15 @@ {{t 'resources.session-recording.title_plural'}}
- - - {{t 'resources.storage-bucket.title_plural'}} - + {{#if (can 'navigate model' @model collection='storage-buckets')}} + + + {{t 'resources.storage-bucket.title_plural'}} + + {{/if}} {{/if}} {{#if (and diff --git a/ui/admin/tests/acceptance/storage-buckets/list-test.js b/ui/admin/tests/acceptance/storage-buckets/list-test.js new file mode 100644 index 000000000..3821a4631 --- /dev/null +++ b/ui/admin/tests/acceptance/storage-buckets/list-test.js @@ -0,0 +1,139 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import { module, test } from 'qunit'; +import { visit } from '@ember/test-helpers'; +import { setupApplicationTest } from 'admin/tests/helpers'; +import setupMirage from 'ember-cli-mirage/test-support/setup-mirage'; +import { authenticateSession } from 'ember-simple-auth/test-support'; + +module('Acceptance | storage-buckets | list', function (hooks) { + setupApplicationTest(hooks); + setupMirage(hooks); + + let features; + const STORAGE_BUCKET_LINK = 'Storage Buckets'; + + const instances = { + scopes: { + global: null, + org: null, + }, + }; + + const urls = { + globalScope: null, + storageBuckets: null, + }; + + hooks.beforeEach(function () { + instances.scopes.global = this.server.create('scope', { id: 'global' }); + instances.scopes.org = this.server.create('scope', { + type: 'org', + scope: { id: 'global', type: 'global' }, + }); + urls.globalScope = `/scopes/global`; + urls.storageBuckets = `${urls.globalScope}/storage-buckets`; + + features = this.owner.lookup('service:features'); + features.enable('session-recording'); + authenticateSession({}); + }); + + test('users can navigate to storage-buckets with proper authorization', async function (assert) { + assert.expect(3); + + await visit(urls.globalScope); + + assert.true( + instances.scopes.global.authorized_collection_actions[ + 'storage-buckets' + ].includes('list') + ); + assert.true( + instances.scopes.global.authorized_collection_actions[ + 'storage-buckets' + ].includes('create') + ); + assert.dom(`[href="${urls.storageBuckets}"]`).exists(); + }); + + test('user cannot navigate to index without either list or create actions', async function (assert) { + assert.expect(3); + instances.scopes.global.authorized_collection_actions['storage-buckets'] = + []; + + await visit(urls.globalScope); + + assert.false( + instances.scopes.global.authorized_collection_actions[ + 'storage-buckets' + ].includes('list') + ); + assert.false( + instances.scopes.global.authorized_collection_actions[ + 'storage-buckets' + ].includes('create') + ); + assert + .dom('[title="General"] a:nth-of-type(3)') + .doesNotIncludeText(STORAGE_BUCKET_LINK); + }); + + test('user can navigate to index with only create action', async function (assert) { + assert.expect(3); + instances.scopes.global.authorized_collection_actions['storage-buckets'] = + instances.scopes.global.authorized_collection_actions[ + 'storage-buckets' + ].filter((item) => item !== 'list'); + + await visit(urls.globalScope); + + assert.false( + instances.scopes.global.authorized_collection_actions[ + 'storage-buckets' + ].includes('list') + ); + assert.true( + instances.scopes.global.authorized_collection_actions[ + 'storage-buckets' + ].includes('create') + ); + assert.dom(`[href="${urls.storageBuckets}"]`).exists(); + }); + + test('user can navigate to index with only list action', async function (assert) { + assert.expect(3); + instances.scopes.global.authorized_collection_actions['storage-buckets'] = + instances.scopes.global.authorized_collection_actions[ + 'storage-buckets' + ].filter((item) => item !== 'create'); + + await visit(urls.globalScope); + + assert.true( + instances.scopes.global.authorized_collection_actions[ + 'storage-buckets' + ].includes('list') + ); + assert.false( + instances.scopes.global.authorized_collection_actions[ + 'storage-buckets' + ].includes('create') + ); + assert.dom(`[href="${urls.storageBuckets}"]`).exists(); + }); + + test('user cannot navigate to index when feature is disabled', async function (assert) { + assert.expect(1); + features.disable('session-recording'); + + await visit(urls.globalScope); + + assert + .dom('[title="General"] a:nth-of-type(2)') + .doesNotIncludeText(STORAGE_BUCKET_LINK); + }); +}); diff --git a/ui/admin/tests/acceptance/storage-buckets/read-test.js b/ui/admin/tests/acceptance/storage-buckets/read-test.js new file mode 100644 index 000000000..e734e79f7 --- /dev/null +++ b/ui/admin/tests/acceptance/storage-buckets/read-test.js @@ -0,0 +1,57 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import { module, test } from 'qunit'; +import { visit, currentURL, click } from '@ember/test-helpers'; +import { setupApplicationTest } from 'admin/tests/helpers'; +import setupMirage from 'ember-cli-mirage/test-support/setup-mirage'; +import a11yAudit from 'ember-a11y-testing/test-support/audit'; +import { authenticateSession } from 'ember-simple-auth/test-support'; + +module('Acceptance | storage-buckets | read', function (hooks) { + setupApplicationTest(hooks); + setupMirage(hooks); + + let features; + + const instances = { + scopes: { + global: null, + org: null, + }, + }; + + const urls = { + globalScope: null, + storageBuckets: null, + }; + + hooks.beforeEach(function () { + instances.scopes.global = this.server.create('scope', { id: 'global' }); + instances.scopes.org = this.server.create('scope', { + type: 'org', + scope: { id: 'global', type: 'global' }, + }); + instances.storageBucket = this.server.create('storage-bucket', { + scope: instances.scopes.global, + }); + urls.globalScope = `/scopes/global`; + urls.storageBuckets = `${urls.globalScope}/storage-buckets`; + + features = this.owner.lookup('service:features'); + features.enable('session-recording'); + authenticateSession({}); + }); + + test('visiting storage buckets', async function (assert) { + assert.expect(1); + await visit(urls.globalScope); + await a11yAudit(); + + await click(`[href="${urls.storageBuckets}"]`); + + assert.strictEqual(currentURL(), urls.storageBuckets); + }); +}); From 78392ff9b46288ae3f2a036e12e72a62ccdd3cd2 Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Date: Wed, 8 Mar 2023 10:02:42 -0800 Subject: [PATCH 023/193] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20Add=20component?= =?UTF-8?q?=20sidebar=20in=20Admin=20UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add layout component sidebar in Admin UI and a view (Session recordings) already using it βœ… Closes: ICU-8145 --- .../app/components/layout/sidebar/index.hbs | 8 +++++ ui/admin/app/styles/app.scss | 15 +++++++++ .../session-recording/index.hbs | 33 +++++++++++++------ .../components/layout/sidebar-test.js | 23 +++++++++++++ 4 files changed, 69 insertions(+), 10 deletions(-) create mode 100644 ui/admin/app/components/layout/sidebar/index.hbs create mode 100644 ui/admin/tests/integration/components/layout/sidebar-test.js diff --git a/ui/admin/app/components/layout/sidebar/index.hbs b/ui/admin/app/components/layout/sidebar/index.hbs new file mode 100644 index 000000000..4c5845023 --- /dev/null +++ b/ui/admin/app/components/layout/sidebar/index.hbs @@ -0,0 +1,8 @@ +
+ {{yield + (hash + body=(component 'rose/anonymous' class='layout-sidebar-body') + sidebar=(component 'rose/anonymous' class='layout-sidebar-sidebar') + ) + }} +
\ No newline at end of file diff --git a/ui/admin/app/styles/app.scss b/ui/admin/app/styles/app.scss index 1f305e001..fe37bd3ba 100644 --- a/ui/admin/app/styles/app.scss +++ b/ui/admin/app/styles/app.scss @@ -686,3 +686,18 @@ } /* stylelint-enable selector-class-pattern */ } + +.layout-sidebar { + display: grid; + grid-template-areas: 'body body sidebar'; + + .layout-sidebar-body { + grid-area: body; + } + + .layout-sidebar-sidebar { + display: flex; + flex-direction: column; + grid-area: sidebar; + } +} diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs index 981e709ba..ad5da6ffd 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs @@ -4,16 +4,29 @@ -

{{t 'resources.session-recording.title'}} - {{@model.session_recording_id}}

-

{{t 'resources.session-recording.channel.title'}} - {{@model.channel_connection_id}}

+ + +

+ {{t 'resources.session-recording.title'}} + {{@model.session_recording_id}} +

- - {{@model.channel_connection_id}} - +

+ {{t 'resources.session-recording.channel.title'}} + {{@model.channel_connection_id}} +

+ + + {{@model.channel_connection_id}} + +
+ + +

{{t 'actions.help'}}

+
+
\ No newline at end of file diff --git a/ui/admin/tests/integration/components/layout/sidebar-test.js b/ui/admin/tests/integration/components/layout/sidebar-test.js new file mode 100644 index 000000000..c90c9a9c4 --- /dev/null +++ b/ui/admin/tests/integration/components/layout/sidebar-test.js @@ -0,0 +1,23 @@ +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'admin/tests/helpers'; +import { render } from '@ember/test-helpers'; +import { hbs } from 'ember-cli-htmlbars'; + +module('Integration | Component | layout/sidebar', function (hooks) { + setupRenderingTest(hooks); + + test('it renders', async function (assert) { + await render(hbs` + + Body content + Sidebar content + + `); + + assert.dom('.layout-sidebar').isVisible(); + assert.dom('.layout-sidebar-body').isVisible(); + assert.dom('.layout-sidebar-body').hasText('Body content'); + assert.dom('.layout-sidebar-sidebar').isVisible(); + assert.dom('.layout-sidebar-sidebar').hasText('Sidebar content'); + }); +}); From 9e42712b9fc8657ab044a7071120f3bda79a9525 Mon Sep 17 00:00:00 2001 From: Cameron Perera Date: Wed, 8 Mar 2023 12:30:58 -0600 Subject: [PATCH 024/193] =?UTF-8?q?refactor:=20=F0=9F=92=A1=20style=20embe?= =?UTF-8?q?r-asciinema-player?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit βœ… Closes: ICU-8380 --- .../session-recording/player/index.hbs | 2 +- ui/admin/app/styles/app.scss | 63 +++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/ui/admin/app/components/session-recording/player/index.hbs b/ui/admin/app/components/session-recording/player/index.hbs index 377faca68..e3244d9bd 100644 --- a/ui/admin/app/components/session-recording/player/index.hbs +++ b/ui/admin/app/components/session-recording/player/index.hbs @@ -1,4 +1,4 @@ -
+
Date: Wed, 8 Mar 2023 11:05:35 -0800 Subject: [PATCH 025/193] Delete sidebar inner styles --- ui/admin/app/styles/app.scss | 2 -- 1 file changed, 2 deletions(-) diff --git a/ui/admin/app/styles/app.scss b/ui/admin/app/styles/app.scss index fe37bd3ba..9bbe06c90 100644 --- a/ui/admin/app/styles/app.scss +++ b/ui/admin/app/styles/app.scss @@ -696,8 +696,6 @@ } .layout-sidebar-sidebar { - display: flex; - flex-direction: column; grid-area: sidebar; } } From cb1524b6cc2ba4003882b84623b5d5e8ed54327f Mon Sep 17 00:00:00 2001 From: Cameron Perera Date: Wed, 8 Mar 2023 13:05:47 -0600 Subject: [PATCH 026/193] =?UTF-8?q?style:=20=F0=9F=92=84=20fix=20lint=20is?= =?UTF-8?q?sues=20for=20player=20styles?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ui/admin/app/styles/app.scss | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ui/admin/app/styles/app.scss b/ui/admin/app/styles/app.scss index 7ca105639..c0859d17b 100644 --- a/ui/admin/app/styles/app.scss +++ b/ui/admin/app/styles/app.scss @@ -715,6 +715,7 @@ a:hover { color: var(--link-color); + /* stylelint-disable selector-class-pattern */ .hds-link-standalone__text { text-decoration-color: var(--link-color); } @@ -738,11 +739,11 @@ .asciinema-player-wrapper { &.hud .control-bar { - bottom: 0rem; + bottom: 0; } .control-bar { - bottom: 0rem; + bottom: 0; background: var(--player-background-color); border-top: var(--player-divider) 0.125rem solid; } From bd3cfab5fdc16b5811f0d134d4e68f826a675c53 Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Date: Wed, 8 Mar 2023 11:39:47 -0800 Subject: [PATCH 027/193] Add media query to layour-sidebar, add grid gap and areas --- ui/admin/app/styles/app.scss | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/ui/admin/app/styles/app.scss b/ui/admin/app/styles/app.scss index 9bbe06c90..f57df4d86 100644 --- a/ui/admin/app/styles/app.scss +++ b/ui/admin/app/styles/app.scss @@ -690,6 +690,9 @@ .layout-sidebar { display: grid; grid-template-areas: 'body body sidebar'; + grid-template-columns: repeat(3, 1fr); + grid-template-rows: auto 1fr; + gap: 1em; .layout-sidebar-body { grid-area: body; @@ -699,3 +702,12 @@ grid-area: sidebar; } } + +@media (max-width: media.width(large)) { + .layout-sidebar { + grid-template-columns: 1fr; + grid-template-areas: + 'body' + 'sidebar'; + } +} From 6a5a27348b140b011fee4de3784418a1022d7fdf Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Date: Wed, 8 Mar 2023 11:42:38 -0800 Subject: [PATCH 028/193] Change unit of measurement --- ui/admin/app/styles/app.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/admin/app/styles/app.scss b/ui/admin/app/styles/app.scss index f57df4d86..d7b5449d1 100644 --- a/ui/admin/app/styles/app.scss +++ b/ui/admin/app/styles/app.scss @@ -692,7 +692,7 @@ grid-template-areas: 'body body sidebar'; grid-template-columns: repeat(3, 1fr); grid-template-rows: auto 1fr; - gap: 1em; + gap: 2rem; .layout-sidebar-body { grid-area: body; From 4f0b3f71fd8d4ac50e7f3a7e886cf3183219096b Mon Sep 17 00:00:00 2001 From: lisbet-alvarez <107949262+lisbet-alvarez@users.noreply.github.com> Date: Thu, 9 Mar 2023 08:57:50 -0800 Subject: [PATCH 029/193] =?UTF-8?q?chore:=20=F0=9F=A4=96=20can=20abilities?= =?UTF-8?q?=20for=20storage=20bucket=20(#97)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: πŸ€– add can list, navigate, and create βœ… Closes: ICU-8244 --- addons/api/addon/abilities/storage-bucket.js | 41 ++++ addons/api/app/abilities/storage-bucket.js | 6 + ui/admin/app/abilities/storage-bucket.js | 31 +++ .../unit/abilities/storage-bucket-test.js | 224 ++++++++++++++++++ 4 files changed, 302 insertions(+) create mode 100644 addons/api/addon/abilities/storage-bucket.js create mode 100644 addons/api/app/abilities/storage-bucket.js create mode 100644 ui/admin/app/abilities/storage-bucket.js create mode 100644 ui/admin/tests/unit/abilities/storage-bucket-test.js diff --git a/addons/api/addon/abilities/storage-bucket.js b/addons/api/addon/abilities/storage-bucket.js new file mode 100644 index 000000000..d521b8ad4 --- /dev/null +++ b/addons/api/addon/abilities/storage-bucket.js @@ -0,0 +1,41 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import ModelAbility from './model'; + +/** + * Provides abilities for storage buckets. + */ +export default class StorageBucketAbility extends ModelAbility { + // =services + + // =permissions + + /** + * Only "known" storage bucket types may be read. + * @type {boolean} + */ + get canRead() { + return !this.model.isUnknown && this.hasAuthorizedAction('read'); + } + + /** + * Storage buckets can only exist within global and org scopes. + * @type {boolean} + */ + get canCreate() { + return ( + this.hasAuthorizedCollectionAction('create') && + (this.model.isGlobal || this.model.isOrg) + ); + } + + get canList() { + return ( + this.hasAuthorizedCollectionAction('list') && + (this.model.isGlobal || this.model.isOrg) + ); + } +} diff --git a/addons/api/app/abilities/storage-bucket.js b/addons/api/app/abilities/storage-bucket.js new file mode 100644 index 000000000..ed343c8d4 --- /dev/null +++ b/addons/api/app/abilities/storage-bucket.js @@ -0,0 +1,6 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +export { default } from 'api/abilities/storage-bucket'; diff --git a/ui/admin/app/abilities/storage-bucket.js b/ui/admin/app/abilities/storage-bucket.js new file mode 100644 index 000000000..a34d0b9d3 --- /dev/null +++ b/ui/admin/app/abilities/storage-bucket.js @@ -0,0 +1,31 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import StorageBucketAbility from 'api/abilities/storage-bucket'; +import { inject as service } from '@ember/service'; + +export default class OverrideStorageBucketAbility extends StorageBucketAbility { + // =service + @service features; + + /** + * This override ensures that storage buckets may be read only if the + * session-recording feature flag is enabled. + */ + get canRead() { + return this.features.isEnabled('session-recording') ? super.canRead : false; + } + + /** + * This override ensures that storage buckets can only be presented in the global scope. + */ + get canList() { + return this.hasAuthorizedCollectionAction('list') && this.model.isGlobal; + } + + get canNavigate() { + return this.canCreate || this.canList; + } +} diff --git a/ui/admin/tests/unit/abilities/storage-bucket-test.js b/ui/admin/tests/unit/abilities/storage-bucket-test.js new file mode 100644 index 000000000..3961c60dd --- /dev/null +++ b/ui/admin/tests/unit/abilities/storage-bucket-test.js @@ -0,0 +1,224 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; +import { + TYPE_STORAGE_BUCKET_PLUGIN, + TYPE_STORAGE_BUCKET_PLUGIN_AWS_S3, +} from 'api/models/storage-bucket'; + +module('Unit | Abilities | storage-bucket', function (hooks) { + setupTest(hooks); + + let features; + + hooks.beforeEach(function () { + features = this.owner.lookup('service:features'); + features.enable('session-recording'); + }); + + test('can read storage bucket when authorized and feature is enabled', function (assert) { + assert.expect(1); + const canService = this.owner.lookup('service:can'); + const store = this.owner.lookup('service:store'); + + const storageBucket = store.createRecord('storage-bucket', { + authorized_actions: ['read'], + type: TYPE_STORAGE_BUCKET_PLUGIN, + compositeType: TYPE_STORAGE_BUCKET_PLUGIN_AWS_S3, + }); + + assert.true(canService.can('read storage-bucket', storageBucket)); + }); + + test('cannot read storage bucket when unauthorized and feature is enabled', function (assert) { + assert.expect(1); + const canService = this.owner.lookup('service:can'); + const store = this.owner.lookup('service:store'); + + const storageBucket = store.createRecord('storage-bucket', { + authorized_actions: [], + type: TYPE_STORAGE_BUCKET_PLUGIN, + compositeType: TYPE_STORAGE_BUCKET_PLUGIN_AWS_S3, + }); + + assert.false(canService.can('read storage-bucket', storageBucket)); + }); + + test('cannot read storage bucket when authorized and feature is disabled', function (assert) { + assert.expect(1); + const canService = this.owner.lookup('service:can'); + const store = this.owner.lookup('service:store'); + features.disable('session-recording'); + + const storageBucket = store.createRecord('storage-bucket', { + authorized_actions: ['read'], + type: TYPE_STORAGE_BUCKET_PLUGIN, + compositeType: TYPE_STORAGE_BUCKET_PLUGIN_AWS_S3, + }); + + assert.false(canService.can('read storage-bucket', storageBucket)); + }); + + test('cannot read storage bucket when unauthorized and feature is disabled', function (assert) { + assert.expect(1); + const canService = this.owner.lookup('service:can'); + const store = this.owner.lookup('service:store'); + features.disable('session-recording'); + + const storageBucket = store.createRecord('storage-bucket', { + authorized_actions: [], + type: TYPE_STORAGE_BUCKET_PLUGIN, + compositeType: TYPE_STORAGE_BUCKET_PLUGIN_AWS_S3, + }); + + assert.false(canService.can('read storage-bucket', storageBucket)); + }); + + test('can list storage bucket when authorized and in global scope', function (assert) { + assert.expect(1); + const canService = this.owner.lookup('service:can'); + const store = this.owner.lookup('service:store'); + + const scopeModel = store.createRecord('scope', { + authorized_collection_actions: { 'storage-buckets': ['list'] }, + type: 'global', + id: 'global', + }); + + assert.true( + canService.can('list storage-bucket', scopeModel, { + collection: 'storage-buckets', + }) + ); + }); + + test('cannot list storage bucket when unauthorized and in global scope', function (assert) { + assert.expect(1); + const canService = this.owner.lookup('service:can'); + const store = this.owner.lookup('service:store'); + + const scopeModel = store.createRecord('scope', { + authorized_collection_actions: { 'storage-buckets': [] }, + type: 'global', + id: 'global', + }); + + assert.false( + canService.can('list storage-bucket', scopeModel, { + collection: 'storage-buckets', + }) + ); + }); + + test('cannot list storage bucket when authorized and in org scope', function (assert) { + assert.expect(1); + const canService = this.owner.lookup('service:can'); + const store = this.owner.lookup('service:store'); + + const scopeModel = store.createRecord('scope', { + authorized_collection_actions: { 'storage-buckets': ['list'] }, + type: 'org', + id: 'o_123', + }); + + assert.false( + canService.can('list storage-bucket', scopeModel, { + collection: 'storage-buckets', + }) + ); + }); + + test('can create storage bucket when authorized and in global scope', function (assert) { + assert.expect(1); + const canService = this.owner.lookup('service:can'); + const store = this.owner.lookup('service:store'); + + const scopeModel = store.createRecord('scope', { + authorized_collection_actions: { 'storage-buckets': ['create'] }, + type: 'global', + id: 'global', + }); + + assert.true( + canService.can('create storage-bucket', scopeModel, { + collection: 'storage-buckets', + }) + ); + }); + + test('can create storage bucket when authorized and in org scope', function (assert) { + assert.expect(1); + const canService = this.owner.lookup('service:can'); + const store = this.owner.lookup('service:store'); + + const scopeModel = store.createRecord('scope', { + authorized_collection_actions: { 'storage-buckets': ['create'] }, + type: 'org', + id: 'o_123', + }); + + assert.true( + canService.can('create storage-bucket', scopeModel, { + collection: 'storage-buckets', + }) + ); + }); + + test('cannot create storage bucket when authorized and in project scope', function (assert) { + assert.expect(1); + const canService = this.owner.lookup('service:can'); + const store = this.owner.lookup('service:store'); + + const scopeModel = store.createRecord('scope', { + authorized_collection_actions: { 'storage-buckets': ['create'] }, + type: 'project', + id: 'p_123', + }); + + assert.false( + canService.can('create storage-bucket', scopeModel, { + collection: 'storage-buckets', + }) + ); + }); + + test('cannot create storage bucket when unauthorized', function (assert) { + assert.expect(1); + const canService = this.owner.lookup('service:can'); + const store = this.owner.lookup('service:store'); + + const scopeModel = store.createRecord('scope', { + authorized_collection_actions: { 'storage-buckets': [] }, + type: 'global', + id: 'global', + }); + + assert.false( + canService.can('create storage-bucket', scopeModel, { + collection: 'storage-buckets', + }) + ); + }); + + test('can navigate to storage bucket when authorized', function (assert) { + assert.expect(1); + const canService = this.owner.lookup('service:can'); + const store = this.owner.lookup('service:store'); + + const scopeModel = store.createRecord('scope', { + authorized_collection_actions: { 'storage-buckets': ['create'] }, + type: 'global', + id: 'global', + }); + + assert.true( + canService.can('navigate storage-bucket', scopeModel, { + collection: 'storage-buckets', + }) + ); + }); +}); From 0aedfc1147d2e04a07d62b9398493245ad3513cf Mon Sep 17 00:00:00 2001 From: lisbet-alvarez <107949262+lisbet-alvarez@users.noreply.github.com> Date: Thu, 9 Mar 2023 08:58:29 -0800 Subject: [PATCH 030/193] Icu 8225 create a new link to create storage bucket (#106) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 🎸 add new link to create storage bucket βœ… Closes: ICU-8225 --- .../scopes/scope/storage-buckets.js | 22 ++++++++++++++ .../routes/scopes/scope/storage-buckets.js | 7 ++++- .../scopes/scope/storage-buckets/index.js | 10 ++++++- .../scopes/scope/storage-buckets/index.hbs | 30 ++++++++++++++++++- ui/admin/config/environment.js | 1 + .../scopes/scope/storage-buckets-test.js | 18 +++++++++++ 6 files changed, 85 insertions(+), 3 deletions(-) create mode 100644 ui/admin/app/controllers/scopes/scope/storage-buckets.js create mode 100644 ui/admin/tests/unit/controllers/scopes/scope/storage-buckets-test.js diff --git a/ui/admin/app/controllers/scopes/scope/storage-buckets.js b/ui/admin/app/controllers/scopes/scope/storage-buckets.js new file mode 100644 index 000000000..249913c40 --- /dev/null +++ b/ui/admin/app/controllers/scopes/scope/storage-buckets.js @@ -0,0 +1,22 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import Controller from '@ember/controller'; +import { inject as service } from '@ember/service'; + +export default class ScopesScopeStorageBucketsController extends Controller { + // =services + + @service intl; + + // = attributes + /** + * Translated breadcrumb + * @type {string} + */ + get breadCrumb() { + return this.intl.t('resources.storage-bucket.title_plural'); + } +} diff --git a/ui/admin/app/routes/scopes/scope/storage-buckets.js b/ui/admin/app/routes/scopes/scope/storage-buckets.js index 6c75be9b8..6c01670d9 100644 --- a/ui/admin/app/routes/scopes/scope/storage-buckets.js +++ b/ui/admin/app/routes/scopes/scope/storage-buckets.js @@ -5,4 +5,9 @@ import Route from '@ember/routing/route'; -export default class ScopesScopeStorageBucketsRoute extends Route {} +export default class ScopesScopeStorageBucketsRoute extends Route { + model() { + // Temporary placeholder + return [{ scope_id: 'sb_123456' }]; + } +} diff --git a/ui/admin/app/routes/scopes/scope/storage-buckets/index.js b/ui/admin/app/routes/scopes/scope/storage-buckets/index.js index 57bbf4b1f..1796e2de3 100644 --- a/ui/admin/app/routes/scopes/scope/storage-buckets/index.js +++ b/ui/admin/app/routes/scopes/scope/storage-buckets/index.js @@ -5,4 +5,12 @@ import Route from '@ember/routing/route'; -export default class ScopesScopeStorageBucketsIndexRoute extends Route {} +export default class ScopesScopeStorageBucketsIndexRoute extends Route { + // =methods + + setupController(controller) { + const scope = this.modelFor('scopes.scope'); + super.setupController(...arguments); + controller.setProperties({ scope }); + } +} diff --git a/ui/admin/app/templates/scopes/scope/storage-buckets/index.hbs b/ui/admin/app/templates/scopes/scope/storage-buckets/index.hbs index 3faf92ead..ead6a3c53 100644 --- a/ui/admin/app/templates/scopes/scope/storage-buckets/index.hbs +++ b/ui/admin/app/templates/scopes/scope/storage-buckets/index.hbs @@ -1,4 +1,32 @@ {{! Copyright (c) HashiCorp, Inc. SPDX-License-Identifier: MPL-2.0 -}} \ No newline at end of file +}} + + + + + + + + {{! TODO: Add valid doc link and description}} +

+ {{t 'resources.storage-bucket.title_plural'}} + +

+
+ + + {{! TODO: Check can create ability using correct file }} + {{#if (can 'create model' this.scope collection='storage-buckets')}} + {{#if @model}} + + {{/if}} + {{/if}} + + + +
\ No newline at end of file diff --git a/ui/admin/config/environment.js b/ui/admin/config/environment.js index 24ebf82ec..7cb123ec6 100644 --- a/ui/admin/config/environment.js +++ b/ui/admin/config/environment.js @@ -117,6 +117,7 @@ module.exports = function (environment) { worker: '/workers', 'worker.manage-workers': '/workers/manage-workers-on-hcp', 'worker-filters': '/worker-filters', + 'storage-bucket': '/storage-buckets', }, }, diff --git a/ui/admin/tests/unit/controllers/scopes/scope/storage-buckets-test.js b/ui/admin/tests/unit/controllers/scopes/scope/storage-buckets-test.js new file mode 100644 index 000000000..fa69f7929 --- /dev/null +++ b/ui/admin/tests/unit/controllers/scopes/scope/storage-buckets-test.js @@ -0,0 +1,18 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import { module, test } from 'qunit'; +import { setupTest } from 'admin/tests/helpers'; + +module('Unit | Controller | scopes/scope/storage-buckets', function (hooks) { + setupTest(hooks); + + test('it exists', function (assert) { + let controller = this.owner.lookup( + 'controller:scopes/scope/storage-buckets' + ); + assert.ok(controller); + }); +}); From 9f4e52153427ef599d0f3311632e2fd5de178e4f Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Date: Thu, 9 Mar 2023 09:34:16 -0800 Subject: [PATCH 031/193] Apply changes requested on PR --- .../components/layout/sidebar/body/index.hbs | 3 +++ .../app/components/layout/sidebar/index.hbs | 4 ++-- .../layout/sidebar/sidebar/index.hbs | 3 +++ .../session-recording/index.hbs | 8 ++++---- .../components/layout/sidebar-test.js | 4 ++-- .../components/layout/sidebar/body-test.js | 18 ++++++++++++++++++ .../components/layout/sidebar/sidebar-test.js | 18 ++++++++++++++++++ 7 files changed, 50 insertions(+), 8 deletions(-) create mode 100644 ui/admin/app/components/layout/sidebar/body/index.hbs create mode 100644 ui/admin/app/components/layout/sidebar/sidebar/index.hbs create mode 100644 ui/admin/tests/integration/components/layout/sidebar/body-test.js create mode 100644 ui/admin/tests/integration/components/layout/sidebar/sidebar-test.js diff --git a/ui/admin/app/components/layout/sidebar/body/index.hbs b/ui/admin/app/components/layout/sidebar/body/index.hbs new file mode 100644 index 000000000..d905ec2e1 --- /dev/null +++ b/ui/admin/app/components/layout/sidebar/body/index.hbs @@ -0,0 +1,3 @@ +
+ {{yield}} +
\ No newline at end of file diff --git a/ui/admin/app/components/layout/sidebar/index.hbs b/ui/admin/app/components/layout/sidebar/index.hbs index 4c5845023..8e66b15a7 100644 --- a/ui/admin/app/components/layout/sidebar/index.hbs +++ b/ui/admin/app/components/layout/sidebar/index.hbs @@ -1,8 +1,8 @@
{{yield (hash - body=(component 'rose/anonymous' class='layout-sidebar-body') - sidebar=(component 'rose/anonymous' class='layout-sidebar-sidebar') + Body=(component 'layout/sidebar/body') + Sidebar=(component 'layout/sidebar/sidebar') ) }}
\ No newline at end of file diff --git a/ui/admin/app/components/layout/sidebar/sidebar/index.hbs b/ui/admin/app/components/layout/sidebar/sidebar/index.hbs new file mode 100644 index 000000000..4c986569d --- /dev/null +++ b/ui/admin/app/components/layout/sidebar/sidebar/index.hbs @@ -0,0 +1,3 @@ +
+ {{yield}} +
\ No newline at end of file diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs index ad5da6ffd..4bdc99323 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs @@ -5,7 +5,7 @@ - +

{{t 'resources.session-recording.title'}} {{@model.session_recording_id}} @@ -22,11 +22,11 @@ > {{@model.channel_connection_id}} - + - +

{{t 'actions.help'}}

- +
\ No newline at end of file diff --git a/ui/admin/tests/integration/components/layout/sidebar-test.js b/ui/admin/tests/integration/components/layout/sidebar-test.js index c90c9a9c4..95a93d6d5 100644 --- a/ui/admin/tests/integration/components/layout/sidebar-test.js +++ b/ui/admin/tests/integration/components/layout/sidebar-test.js @@ -9,8 +9,8 @@ module('Integration | Component | layout/sidebar', function (hooks) { test('it renders', async function (assert) { await render(hbs` - Body content - Sidebar content + Body content + Sidebar content `); diff --git a/ui/admin/tests/integration/components/layout/sidebar/body-test.js b/ui/admin/tests/integration/components/layout/sidebar/body-test.js new file mode 100644 index 000000000..837a29e59 --- /dev/null +++ b/ui/admin/tests/integration/components/layout/sidebar/body-test.js @@ -0,0 +1,18 @@ +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'admin/tests/helpers'; +import { render } from '@ember/test-helpers'; +import { hbs } from 'ember-cli-htmlbars'; + +module('Integration | Component | layout/sidebar/body', function (hooks) { + setupRenderingTest(hooks); + + test('it renders', async function (assert) { + await render(hbs` + + template block text + + `); + + assert.dom(this.element).hasText('template block text'); + }); +}); diff --git a/ui/admin/tests/integration/components/layout/sidebar/sidebar-test.js b/ui/admin/tests/integration/components/layout/sidebar/sidebar-test.js new file mode 100644 index 000000000..ec42c3488 --- /dev/null +++ b/ui/admin/tests/integration/components/layout/sidebar/sidebar-test.js @@ -0,0 +1,18 @@ +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'admin/tests/helpers'; +import { render } from '@ember/test-helpers'; +import { hbs } from 'ember-cli-htmlbars'; + +module('Integration | Component | layout/sidebar/sidebar', function (hooks) { + setupRenderingTest(hooks); + + test('it renders', async function (assert) { + await render(hbs` + + template block text + + `); + + assert.dom(this.element).hasText('template block text'); + }); +}); From 1ec6bd28f01f637823fd18ef68b10559fc3a1da0 Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Date: Thu, 9 Mar 2023 11:45:28 -0800 Subject: [PATCH 032/193] Fix lint issue --- ui/admin/app/styles/app.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/ui/admin/app/styles/app.scss b/ui/admin/app/styles/app.scss index b3d9f1124..c1bc62db0 100644 --- a/ui/admin/app/styles/app.scss +++ b/ui/admin/app/styles/app.scss @@ -750,6 +750,7 @@ } } } + // Layout - Sidebar .layout-sidebar { display: grid; From 498091c55058e9b0a81af693829f75c0018c02a0 Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Date: Thu, 9 Mar 2023 11:58:26 -0800 Subject: [PATCH 033/193] Add Sidebar layout component within channel view --- .../channels-by-connection/channel.hbs | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs index 22b74e153..015c8a546 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs @@ -1,5 +1,19 @@ {{page-title (t 'resources.session-recording.channel.title')}} -

{{@model.scope_id}}

- -{{outlet}} \ No newline at end of file + + +

{{t 'resources.session-recording.channel.title'}}

+
+ + + + + + + + +

{{@model.scope_id}}

+
+
+
+
\ No newline at end of file From f65bf21a3322c7fb9be10200bc905eb2fd30084f Mon Sep 17 00:00:00 2001 From: Devon Anderson Date: Fri, 10 Mar 2023 13:41:57 -0500 Subject: [PATCH 034/193] Icu 8227 display storage buckets (#113) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * create list UI for storage-buckets * refactor: πŸ’‘ removed future code Removed code that was used in testing βœ… Closes: ICU-8227 * Update app.scss fixed lint * Update ui/admin/app/templates/scopes/scope/storage-buckets/index.hbs Co-authored-by: Zhihe Li * Update addons/core/translations/resources/en-us.yaml Co-authored-by: Zhihe Li * Update ui/admin/app/templates/scopes/scope/storage-buckets/index.hbs Co-authored-by: Zhihe Li * Update en-us.yaml moving this into forms translation * Update en-us.yaml moving edit into `actions` translations for `storage-bucket` dropdown * refactor: πŸ’‘ yaml cleanup Refactored storage bucket list translations βœ… Closes: ICU-8227 * refactor: πŸ’‘ refactored storage-bucket list Refactored `storage-bucket` list to have copyable id and removed `border-collapse` from `reset.scss` that was causing `HDS::Table` not to have rounded edges. βœ… Closes: ICU-8227 * Update ui/admin/app/routes/scopes/scope/storage-buckets.js Co-authored-by: lisbet-alvarez <107949262+lisbet-alvarez@users.noreply.github.com> * refactor: πŸ’‘ quick refactor for scope.hbs Refactored sidebar navigation for `storage-bucket` to include navigate override ability for `storage-bucket` βœ… Closes: ICU-8227 * refactor: πŸ’‘ refactored hbs file for storage-bucket list Removed unneeded storage bucket list wrapper div. βœ… Closes: ICU-8227 --------- Co-authored-by: Zhihe Li Co-authored-by: lisbet-alvarez <107949262+lisbet-alvarez@users.noreply.github.com> --- addons/core/translations/actions/en-us.yaml | 1 + addons/core/translations/resources/en-us.yaml | 8 ++ .../routes/scopes/scope/storage-buckets.js | 33 ++++++++- .../scope/storage-buckets/storage-bucket.js | 19 ++++- ui/admin/app/styles/app.scss | 4 + ui/admin/app/templates/scopes/scope.hbs | 7 +- .../scopes/scope/storage-buckets/index.hbs | 74 ++++++++++++++++++- .../scope/storage-buckets/storage-bucket.hbs | 1 - 8 files changed, 136 insertions(+), 11 deletions(-) diff --git a/addons/core/translations/actions/en-us.yaml b/addons/core/translations/actions/en-us.yaml index 125ea3f51..5cf7a182a 100644 --- a/addons/core/translations/actions/en-us.yaml +++ b/addons/core/translations/actions/en-us.yaml @@ -3,6 +3,7 @@ add: Add cancel: Cancel +edit: Edit delete: Delete remove: Remove discard: Discard diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml index 16326b2f2..0a137c8c4 100644 --- a/addons/core/translations/resources/en-us.yaml +++ b/addons/core/translations/resources/en-us.yaml @@ -224,6 +224,14 @@ storage-bucket: title_plural: Storage Buckets titles: new: New Storage Bucket + aws: AWS + global: Global + orgs: Orgs + actions: + delete: Delete Storage Bucket + form: + scope: Scope + provider: Provider project: title: Project title_plural: Projects diff --git a/ui/admin/app/routes/scopes/scope/storage-buckets.js b/ui/admin/app/routes/scopes/scope/storage-buckets.js index 6c01670d9..56b2632b6 100644 --- a/ui/admin/app/routes/scopes/scope/storage-buckets.js +++ b/ui/admin/app/routes/scopes/scope/storage-buckets.js @@ -4,10 +4,37 @@ */ import Route from '@ember/routing/route'; +import { inject as service } from '@ember/service'; export default class ScopesScopeStorageBucketsRoute extends Route { - model() { - // Temporary placeholder - return [{ scope_id: 'sb_123456' }]; + // =services + + @service store; + @service intl; + @service session; + @service can; + @service router; + + // =methods + + /** + * If arriving here unauthenticated, redirect to index for further processing. + */ + beforeModel() { + if (!this.session.isAuthenticated) this.router.transitionTo('index'); } + + /** + * Load all storage buckets under current scope. + * @return {Promise{[StorageBucketModel]}} + */ + async model() { + const scope = this.modelFor('scopes.scope'); + const { id: scope_id } = scope; + if (this.can.can('list storage-bucket', scope, { collection: 'storage-buckets' })) { + return this.store.query('storage-bucket', { scope_id }); + } + } + + // =actions } diff --git a/ui/admin/app/routes/scopes/scope/storage-buckets/storage-bucket.js b/ui/admin/app/routes/scopes/scope/storage-buckets/storage-bucket.js index 8bf0c5ef4..ac33f0f36 100644 --- a/ui/admin/app/routes/scopes/scope/storage-buckets/storage-bucket.js +++ b/ui/admin/app/routes/scopes/scope/storage-buckets/storage-bucket.js @@ -4,11 +4,22 @@ */ import Route from '@ember/routing/route'; +import { inject as service } from '@ember/service'; export default class ScopesScopeStorageBucketsStorageBucketRoute extends Route { - model() { - return { - scope_id: 'sb_1234567890', - }; + // =services + + @service store; + + // =methods + + /** + * Load a user in current scope. + * @param {object} params + * @param {string} params.storage_bucket_id + * @return {StorageBucketModel} + */ + async model({ storage_bucket_id }) { + return this.store.findRecord('storage-bucket', storage_bucket_id); } } diff --git a/ui/admin/app/styles/app.scss b/ui/admin/app/styles/app.scss index c1bc62db0..f71bcf07e 100644 --- a/ui/admin/app/styles/app.scss +++ b/ui/admin/app/styles/app.scss @@ -776,3 +776,7 @@ 'sidebar'; } } + +.storage-bucket-list { + border-collapse: revert; +} diff --git a/ui/admin/app/templates/scopes/scope.hbs b/ui/admin/app/templates/scopes/scope.hbs index 22be84374..67694f447 100644 --- a/ui/admin/app/templates/scopes/scope.hbs +++ b/ui/admin/app/templates/scopes/scope.hbs @@ -26,13 +26,16 @@ {{t 'resources.org.title_plural'}} - {{! TODO: Check can abilities }} {{#if (feature-flag 'session-recording')}} {{t 'resources.session-recording.title_plural'}} - {{#if (can 'navigate model' @model collection='storage-buckets')}} + {{#if + (can + 'navigate storage-bucket' @model collection='storage-buckets' + ) + }} - + + {{#if @model}} + + <:body as |B|> + + + {{#if (can 'read storage-bucket' B.data)}} + + {{B.data.displayName}} + + {{else}} + {{B.data.displayName}} + {{/if}} + {{#if B.data.description}} +

{{B.data.description}}

+ {{/if}} +
+ + + {{B.data.id}} + + + + {{#if B.data.isAWS}} + + {{else}} + {{B.data.plugin.name}} + {{/if}} + + + {{#if B.data.scopeModel.isGlobal}} + + {{else}} + + {{/if}} + + + {{!TODO: add dropdown for delete and edit actions}} + +
+ +
+ {{else}} + {{!TODO: Render new landing page }} + {{/if}} +
\ No newline at end of file diff --git a/ui/admin/app/templates/scopes/scope/storage-buckets/storage-bucket.hbs b/ui/admin/app/templates/scopes/scope/storage-buckets/storage-bucket.hbs index 1d6ed5ba4..40b29859d 100644 --- a/ui/admin/app/templates/scopes/scope/storage-buckets/storage-bucket.hbs +++ b/ui/admin/app/templates/scopes/scope/storage-buckets/storage-bucket.hbs @@ -5,5 +5,4 @@ {{page-title @model.displayName}} -

{{@model.scope_id}}

{{outlet}} \ No newline at end of file From 7af4625457c8d2acd9c436dda5946c37d0fff66e Mon Sep 17 00:00:00 2001 From: lisbet-alvarez <107949262+lisbet-alvarez@users.noreply.github.com> Date: Fri, 10 Mar 2023 11:03:29 -0800 Subject: [PATCH 035/193] Icu 8226 create an empty screen when there are no storage buckets (#114) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 🎸 add new link to create storage bucket βœ… Closes: ICU-8225 Co-authored-by: Zhihe Li --- addons/core/translations/resources/en-us.yaml | 5 ++ .../scopes/scope/storage-buckets/index.hbs | 46 +++++++++++++++++-- 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml index 0a137c8c4..cb5ae2fc4 100644 --- a/addons/core/translations/resources/en-us.yaml +++ b/addons/core/translations/resources/en-us.yaml @@ -222,6 +222,11 @@ session-recording: storage-bucket: title: Storage Bucket title_plural: Storage Buckets + messages: + none: + title: No storage buckets yet + description: To start using session recording, you need to have an Amazon S3 bucket. + link: Add a new storage bucket titles: new: New Storage Bucket aws: AWS diff --git a/ui/admin/app/templates/scopes/scope/storage-buckets/index.hbs b/ui/admin/app/templates/scopes/scope/storage-buckets/index.hbs index 84973481c..082c294eb 100644 --- a/ui/admin/app/templates/scopes/scope/storage-buckets/index.hbs +++ b/ui/admin/app/templates/scopes/scope/storage-buckets/index.hbs @@ -17,8 +17,9 @@ - {{! TODO: Check can create ability using correct file }} - {{#if (can 'create model' this.scope collection='storage-buckets')}} + {{#if + (can 'create storage-bucket' this.scope collection='storage-buckets') + }} {{#if @model}} {{else}} - {{!TODO: Render new landing page }} + + + + {{#if + (can + 'list storage-bucket' this.scope collection='storage-buckets' + ) + }} + {{t 'resources.storage-bucket.messages.none.description'}} + {{else if (can + 'create storage-bucket' this.scope collection='storage-buckets' + )}} + {{t + 'descriptions.create-but-not-list' + resource=(t 'resources.storage-bucket.title_plural') + }} + {{else}} + {{t + 'descriptions.neither-list-nor-create' + resource=(t 'resources.storage-bucket.title_plural') + }} + {{/if}} + + {{#if + (can + 'create storage-bucket' this.scope collection='storage-buckets' + ) + }} + + {{/if}} + + {{/if}}
\ No newline at end of file From ce83346461108bea8fa0827ddf8ecb1119849dc3 Mon Sep 17 00:00:00 2001 From: Zhihe Li Date: Fri, 10 Mar 2023 14:20:58 -0500 Subject: [PATCH 036/193] Icu 8073 mirage recording connection channel (#109) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 🎸 Add mirage data for recordings, connections, channels βœ… Closes: ICU-8073 --- addons/api/addon/serializers/connection.js | 10 +++ addons/api/addon/serializers/recording.js | 9 +++ addons/api/app/serializers/connection.js | 1 + addons/api/app/serializers/recording.js | 1 + addons/api/mirage/config.js | 9 +++ addons/api/mirage/factories/channel.js | 13 ++++ addons/api/mirage/factories/connection.js | 11 ++++ addons/api/mirage/factories/recording.js | 63 +++++++++++++++++++ addons/api/mirage/factories/scope.js | 5 +- addons/api/mirage/factories/storage-bucket.js | 5 ++ .../api/mirage/generated/factories/channel.js | 20 ++++++ .../mirage/generated/factories/connection.js | 20 ++++++ .../mirage/generated/factories/recording.js | 24 +++++++ .../generated/factories/storage-bucket.js | 6 +- addons/api/mirage/models/channel.js | 10 +++ addons/api/mirage/models/connection.js | 11 ++++ addons/api/mirage/models/recording.js | 14 +++++ addons/api/mirage/models/storage-bucket.js | 5 ++ addons/api/mirage/scenarios/default.js | 20 ++++++ addons/api/mirage/serializers/channel.js | 10 +++ addons/api/mirage/serializers/connection.js | 25 ++++++++ addons/api/mirage/serializers/recording.js | 43 +++++++++++++ .../api/mirage/serializers/storage-bucket.js | 5 ++ .../tests/unit/serializers/connection-test.js | 23 +++++++ .../tests/unit/serializers/recording-test.js | 23 +++++++ 25 files changed, 384 insertions(+), 2 deletions(-) create mode 100644 addons/api/addon/serializers/connection.js create mode 100644 addons/api/addon/serializers/recording.js create mode 100644 addons/api/app/serializers/connection.js create mode 100644 addons/api/app/serializers/recording.js create mode 100644 addons/api/mirage/factories/channel.js create mode 100644 addons/api/mirage/factories/connection.js create mode 100644 addons/api/mirage/factories/recording.js create mode 100644 addons/api/mirage/generated/factories/channel.js create mode 100644 addons/api/mirage/generated/factories/connection.js create mode 100644 addons/api/mirage/generated/factories/recording.js create mode 100644 addons/api/mirage/models/channel.js create mode 100644 addons/api/mirage/models/connection.js create mode 100644 addons/api/mirage/models/recording.js create mode 100644 addons/api/mirage/serializers/channel.js create mode 100644 addons/api/mirage/serializers/connection.js create mode 100644 addons/api/mirage/serializers/recording.js create mode 100644 addons/api/tests/unit/serializers/connection-test.js create mode 100644 addons/api/tests/unit/serializers/recording-test.js diff --git a/addons/api/addon/serializers/connection.js b/addons/api/addon/serializers/connection.js new file mode 100644 index 000000000..95c01903b --- /dev/null +++ b/addons/api/addon/serializers/connection.js @@ -0,0 +1,10 @@ +import ApplicationSerializer from './application'; +import { EmbeddedRecordsMixin } from '@ember-data/serializer/rest'; + +export default class ConnectionSerializer extends ApplicationSerializer.extend( + EmbeddedRecordsMixin +) { + attrs = { + channels: { embedded: 'always' }, + }; +} diff --git a/addons/api/addon/serializers/recording.js b/addons/api/addon/serializers/recording.js new file mode 100644 index 000000000..6759db0dd --- /dev/null +++ b/addons/api/addon/serializers/recording.js @@ -0,0 +1,9 @@ +import ApplicationSerializer from './application'; +import { EmbeddedRecordsMixin } from '@ember-data/serializer/rest'; +export default class RecordingSerializer extends ApplicationSerializer.extend( + EmbeddedRecordsMixin +) { + attrs = { + connections: { embedded: 'always' }, + }; +} diff --git a/addons/api/app/serializers/connection.js b/addons/api/app/serializers/connection.js new file mode 100644 index 000000000..ab831ba04 --- /dev/null +++ b/addons/api/app/serializers/connection.js @@ -0,0 +1 @@ +export { default } from 'api/serializers/connection'; diff --git a/addons/api/app/serializers/recording.js b/addons/api/app/serializers/recording.js new file mode 100644 index 000000000..921180bea --- /dev/null +++ b/addons/api/app/serializers/recording.js @@ -0,0 +1 @@ +export { default } from 'api/serializers/recording'; diff --git a/addons/api/mirage/config.js b/addons/api/mirage/config.js index d6b519784..62041703a 100644 --- a/addons/api/mirage/config.js +++ b/addons/api/mirage/config.js @@ -680,6 +680,15 @@ function routes() { } ); + // session recordings + this.get( + '/recordings', + ({ recordings }, { queryParams: { scope_id: scopeId } }) => { + return recordings.where({ scopeId }); + } + ); + this.get('/recordings/:id'); + /* Uncomment the following line and the Response import above * Then change the response code to simulate error responses. * this.get('/scopes', () => new Response(505)); diff --git a/addons/api/mirage/factories/channel.js b/addons/api/mirage/factories/channel.js new file mode 100644 index 000000000..812d7da44 --- /dev/null +++ b/addons/api/mirage/factories/channel.js @@ -0,0 +1,13 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import factory from '../generated/factories/channel'; +import generateId from '../helpers/id'; +import { TYPES_CHANNEL as types } from 'api/models/channel'; + +export default factory.extend({ + id: () => generateId('srcc_'), + type: (i) => types[i % types.length], +}); diff --git a/addons/api/mirage/factories/connection.js b/addons/api/mirage/factories/connection.js new file mode 100644 index 000000000..455c4941f --- /dev/null +++ b/addons/api/mirage/factories/connection.js @@ -0,0 +1,11 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import factory from '../generated/factories/connection'; +import generateId from '../helpers/id'; + +export default factory.extend({ + id: () => generateId('src_'), +}); diff --git a/addons/api/mirage/factories/recording.js b/addons/api/mirage/factories/recording.js new file mode 100644 index 000000000..1c39abf09 --- /dev/null +++ b/addons/api/mirage/factories/recording.js @@ -0,0 +1,63 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import factory from '../generated/factories/recording'; +import permissions from '../helpers/permissions'; +import generateId from '../helpers/id'; +import { faker } from '@faker-js/faker'; +import { trait } from 'miragejs'; +import { TYPES_RECORDING as types } from 'api/models/recording'; + +const pickRandomElement = (arr) => faker.helpers.arrayElement(arr); +export default factory.extend({ + id: () => generateId('sr_'), + + // Cycle through available types + type: (i) => types[i % types.length], + + authorized_actions: () => + permissions.authorizedActionsFor('recording') || ['no-op', 'read', 'list'], + + withNonExistingUserAndTarget: trait({ + afterCreate(recording, server) { + const user = pickRandomElement(server.schema.users.all().models); + user.id = 'deleted_user'; + const session = pickRandomElement(server.schema.sessions.all().models); + session.id = 'deleted_session'; + const target = session.target; + target.id = 'deleted_target'; + + recording.update({ + user, + target, + session, + }); + }, + }), + + withExistingUserAndTarget: trait({ + afterCreate(recording, server) { + const user = pickRandomElement(server.schema.users.all().models); + const session = pickRandomElement(server.schema.sessions.all().models); + const target = session.target; + + recording.update({ + user, + target, + session, + }); + }, + }), + + withConnectionAndChannels: trait({ + afterCreate(recording, server) { + server + .createList('connection', 3, { recording }) + .forEach((connection) => { + server.createList('channel', 3, { connection }); + }); + }, + }), +}); diff --git a/addons/api/mirage/factories/scope.js b/addons/api/mirage/factories/scope.js index eb8cf99bd..a61f252ee 100644 --- a/addons/api/mirage/factories/scope.js +++ b/addons/api/mirage/factories/scope.js @@ -30,7 +30,6 @@ export default factory.extend({ 'credential-stores': ['create', 'list'], 'auth-methods': ['create', 'list'], 'host-catalogs': ['create', 'list'], - 'storage-buckets': ['create', 'list'], }; // Worker permissions only available on the global scope @@ -38,6 +37,10 @@ export default factory.extend({ collectionActions.workers = ['create:worker-led', 'list']; } + if (this.type === 'global' || this.type === 'org') { + collectionActions['storage-buckets'] = ['create', 'list']; + } + return collectionActions; }, diff --git a/addons/api/mirage/factories/storage-bucket.js b/addons/api/mirage/factories/storage-bucket.js index 2145f6ed1..0946e5dae 100644 --- a/addons/api/mirage/factories/storage-bucket.js +++ b/addons/api/mirage/factories/storage-bucket.js @@ -1,3 +1,8 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + import factory from '../generated/factories/storage-bucket'; import permissions from '../helpers/permissions'; import { faker } from '@faker-js/faker'; diff --git a/addons/api/mirage/generated/factories/channel.js b/addons/api/mirage/generated/factories/channel.js new file mode 100644 index 000000000..e4e37b0f4 --- /dev/null +++ b/addons/api/mirage/generated/factories/channel.js @@ -0,0 +1,20 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import { Factory } from 'miragejs'; +import { faker } from '@faker-js/faker'; + +/** + * GeneratedChannelModelFactory + */ +export default Factory.extend({ + bytes_up: () => faker.datatype.number(), + bytes_down: () => faker.datatype.number(), + errors: () => faker.datatype.number({ max: 10 }), + started_time() { + return faker.date.recent(3, this.finished_time); + }, + finished_time: () => faker.date.recent(), +}); diff --git a/addons/api/mirage/generated/factories/connection.js b/addons/api/mirage/generated/factories/connection.js new file mode 100644 index 000000000..c58040ded --- /dev/null +++ b/addons/api/mirage/generated/factories/connection.js @@ -0,0 +1,20 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import { Factory } from 'miragejs'; +import { faker } from '@faker-js/faker'; + +/** + * GeneratedConnectionModelFactory + */ +export default Factory.extend({ + bytes_up: () => faker.datatype.number(), + bytes_down: () => faker.datatype.number(), + errors: () => faker.datatype.number({ max: 10 }), + started_time() { + return faker.date.recent(3, this.finished_time); + }, + finished_time: () => faker.date.recent(), +}); diff --git a/addons/api/mirage/generated/factories/recording.js b/addons/api/mirage/generated/factories/recording.js new file mode 100644 index 000000000..51824fd59 --- /dev/null +++ b/addons/api/mirage/generated/factories/recording.js @@ -0,0 +1,24 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import { Factory } from 'miragejs'; +import { faker } from '@faker-js/faker'; + +/** + * GeneratedRecordModelFactory + */ +export default Factory.extend({ + bytes_up: () => faker.datatype.number(), + bytes_down: () => faker.datatype.number(), + errors: () => faker.datatype.number({ max: 10 }), + started_time() { + return faker.date.recent(3, this.finished_time); + }, + finished_time() { + return faker.date.recent(1, this.updated_time); + }, + updated_time: () => faker.date.recent(), + deleted_on: () => faker.date.soon(), +}); diff --git a/addons/api/mirage/generated/factories/storage-bucket.js b/addons/api/mirage/generated/factories/storage-bucket.js index f8346f8c6..82be1797b 100644 --- a/addons/api/mirage/generated/factories/storage-bucket.js +++ b/addons/api/mirage/generated/factories/storage-bucket.js @@ -1,3 +1,8 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + import { Factory } from 'miragejs'; import { faker } from '@faker-js/faker'; @@ -5,7 +10,6 @@ import { faker } from '@faker-js/faker'; * GeneratedStorageBucketModelFactory */ export default Factory.extend({ - type: 'plugin', name: () => faker.random.words(), description: () => faker.random.words(), created_time: () => faker.date.recent(), diff --git a/addons/api/mirage/models/channel.js b/addons/api/mirage/models/channel.js new file mode 100644 index 000000000..19ee5e425 --- /dev/null +++ b/addons/api/mirage/models/channel.js @@ -0,0 +1,10 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import { belongsTo, Model } from 'miragejs'; + +export default Model.extend({ + connection: belongsTo(), +}); diff --git a/addons/api/mirage/models/connection.js b/addons/api/mirage/models/connection.js new file mode 100644 index 000000000..5706ffe4b --- /dev/null +++ b/addons/api/mirage/models/connection.js @@ -0,0 +1,11 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import { belongsTo, hasMany, Model } from 'miragejs'; + +export default Model.extend({ + recording: belongsTo(), + channels: hasMany(), +}); diff --git a/addons/api/mirage/models/recording.js b/addons/api/mirage/models/recording.js new file mode 100644 index 000000000..ec60ca095 --- /dev/null +++ b/addons/api/mirage/models/recording.js @@ -0,0 +1,14 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import { belongsTo, hasMany, Model } from 'miragejs'; + +export default Model.extend({ + scope: belongsTo(), + user: belongsTo(), + session: belongsTo(), + target: belongsTo(), + connections: hasMany(), +}); diff --git a/addons/api/mirage/models/storage-bucket.js b/addons/api/mirage/models/storage-bucket.js index 27d40334d..a68d129c9 100644 --- a/addons/api/mirage/models/storage-bucket.js +++ b/addons/api/mirage/models/storage-bucket.js @@ -1,3 +1,8 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + import { belongsTo } from 'miragejs'; import Model from './base'; export default Model.extend({ diff --git a/addons/api/mirage/scenarios/default.js b/addons/api/mirage/scenarios/default.js index eb8531c2f..e174d7d79 100644 --- a/addons/api/mirage/scenarios/default.js +++ b/addons/api/mirage/scenarios/default.js @@ -113,4 +113,24 @@ export default function (server) { // Session Recordings and Storage Buckets server.createList('storage-bucket', 3, { scope: globalScope }); server.createList('storage-bucket', 2, { scope: orgScope }); + server.createList( + 'recording', + 3, + { scope: globalScope }, + 'withConnectionAndChannels', + 'withExistingUserAndTarget' + ); + server.create( + 'recording', + { scope: globalScope }, + 'withConnectionAndChannels', + 'withNonExistingUserAndTarget' + ); + server.createList( + 'recording', + 2, + { scope: orgScope }, + 'withConnectionAndChannels', + 'withExistingUserAndTarget' + ); } diff --git a/addons/api/mirage/serializers/channel.js b/addons/api/mirage/serializers/channel.js new file mode 100644 index 000000000..839e46f34 --- /dev/null +++ b/addons/api/mirage/serializers/channel.js @@ -0,0 +1,10 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import ApplicationSerializer from './application'; + +export default ApplicationSerializer.extend({ + modelName: 'channel', +}); diff --git a/addons/api/mirage/serializers/connection.js b/addons/api/mirage/serializers/connection.js new file mode 100644 index 000000000..6de18bbec --- /dev/null +++ b/addons/api/mirage/serializers/connection.js @@ -0,0 +1,25 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import ApplicationSerializer from './application'; +import ChannelSerializer from './channel'; + +export default ApplicationSerializer.extend({ + modelName: 'connection', + _hashForModel(model) { + const json = ApplicationSerializer.prototype._hashForModel.apply( + this, + arguments + ); + const { channels } = this.schema; + if (model.channelIds) { + json.channels = model.channelIds.map((id) => { + const channel = channels.find(id); + return ChannelSerializer.prototype._hashForModel.apply(this, [channel]); + }); + } + return json; + }, +}); diff --git a/addons/api/mirage/serializers/recording.js b/addons/api/mirage/serializers/recording.js new file mode 100644 index 000000000..a4ce487d3 --- /dev/null +++ b/addons/api/mirage/serializers/recording.js @@ -0,0 +1,43 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import ApplicationSerializer from './application'; +import ConnectionSerializer from './connection'; +import UserSerializer from './user'; +import TargetSerializer from './target'; + +export default ApplicationSerializer.extend({ + modelName: 'recording', + _hashForModel(model) { + const json = ApplicationSerializer.prototype._hashForModel.apply( + this, + arguments + ); + const { connections, users, targets } = this.schema; + + // Manually map our models to the actual embedded json representation + if (model.connectionIds) { + json.connections = model.connectionIds.map((id) => { + const connection = connections.find(id); + return ConnectionSerializer.prototype._hashForModel.apply(this, [ + connection, + ]); + }); + } + if (model.userId) { + const user = users.find(model.userId); + json.user = UserSerializer.prototype._hashForModel.apply(this, [user]); + } + if (model.targetId) { + const target = targets.find(model.targetId); + json.target = TargetSerializer.prototype._hashForModel.apply(this, [ + target, + ]); + } + + json.session_id = model.sessionId; + return json; + }, +}); diff --git a/addons/api/mirage/serializers/storage-bucket.js b/addons/api/mirage/serializers/storage-bucket.js index 7a5bc48df..ca9f87933 100644 --- a/addons/api/mirage/serializers/storage-bucket.js +++ b/addons/api/mirage/serializers/storage-bucket.js @@ -1,3 +1,8 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + import ApplicationSerializer from './application'; export default ApplicationSerializer.extend({ modelName: 'storage-bucket', diff --git a/addons/api/tests/unit/serializers/connection-test.js b/addons/api/tests/unit/serializers/connection-test.js new file mode 100644 index 000000000..02a53897d --- /dev/null +++ b/addons/api/tests/unit/serializers/connection-test.js @@ -0,0 +1,23 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Serializer | connection', function (hooks) { + setupTest(hooks); + + // Replace this with your real tests. + test('it exists', function (assert) { + let store = this.owner.lookup('service:store'); + let serializer = store.serializerFor('connection'); + + assert.ok(serializer); + }); + + test('it serializes records', function (assert) { + let store = this.owner.lookup('service:store'); + let record = store.createRecord('connection', {}); + + let serializedRecord = record.serialize(); + + assert.ok(serializedRecord); + }); +}); diff --git a/addons/api/tests/unit/serializers/recording-test.js b/addons/api/tests/unit/serializers/recording-test.js new file mode 100644 index 000000000..458e02c16 --- /dev/null +++ b/addons/api/tests/unit/serializers/recording-test.js @@ -0,0 +1,23 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Serializer | recording', function (hooks) { + setupTest(hooks); + + // Replace this with your real tests. + test('it exists', function (assert) { + let store = this.owner.lookup('service:store'); + let serializer = store.serializerFor('recording'); + + assert.ok(serializer); + }); + + test('it serializes records', function (assert) { + let store = this.owner.lookup('service:store'); + let record = store.createRecord('recording', {}); + + let serializedRecord = record.serialize(); + + assert.ok(serializedRecord); + }); +}); From 59850651b88180c74cba7ab7c4eea855da96031d Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Date: Tue, 14 Mar 2023 09:56:47 -0700 Subject: [PATCH 037/193] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20Add=20format-tim?= =?UTF-8?q?e-duration=20helper?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add format-time-duration helper to provide human-readable duration string βœ… Closes: ICU-8233 --- .../addon/helpers/format-time-duration.js | 25 +++++++++++ .../core/app/helpers/format-time-duration.js | 1 + addons/core/package.json | 3 +- .../helpers/format-time-duration-test.js | 30 +++++++++++++ .../scopes/scope/session-recordings/index.hbs | 6 +++ yarn.lock | 44 ++++++++++++++----- 6 files changed, 97 insertions(+), 12 deletions(-) create mode 100644 addons/core/addon/helpers/format-time-duration.js create mode 100644 addons/core/app/helpers/format-time-duration.js create mode 100644 addons/core/tests/integration/helpers/format-time-duration-test.js diff --git a/addons/core/addon/helpers/format-time-duration.js b/addons/core/addon/helpers/format-time-duration.js new file mode 100644 index 000000000..bf3e3efe8 --- /dev/null +++ b/addons/core/addon/helpers/format-time-duration.js @@ -0,0 +1,25 @@ +import Helper from '@ember/component/helper'; +import { inject as service } from '@ember/service'; +import DurationUnitFormat from 'intl-unofficial-duration-unit-format'; + +export default class extends Helper { + // =services + @service intl; + + // =methods + /** + * + * @param {number} durationInMs Duration in milliseconds + * @returns localized human-readable duration string. For example, in English "1 hr 23 min 20 sec" + */ + compute([durationInMs]) { + const durationInSeconds = durationInMs / 1000; + const durationFormat = new DurationUnitFormat(this.intl.primaryLocale, { + style: 'short', + format: '{days} {hours} {minutes} {seconds}', + round: true, + }); + + return durationFormat.format(durationInSeconds); + } +} diff --git a/addons/core/app/helpers/format-time-duration.js b/addons/core/app/helpers/format-time-duration.js new file mode 100644 index 000000000..fa028c296 --- /dev/null +++ b/addons/core/app/helpers/format-time-duration.js @@ -0,0 +1 @@ +export { default } from 'core/helpers/format-time-duration'; diff --git a/addons/core/package.json b/addons/core/package.json index e5fb106b7..c3af48918 100644 --- a/addons/core/package.json +++ b/addons/core/package.json @@ -40,7 +40,8 @@ "ember-feature-flags": "^6.0.0", "ember-intl": "^6.0.0-beta.4", "ember-loading": "^2.0.0", - "ember-truth-helpers": "^3.0.0" + "ember-truth-helpers": "^3.0.0", + "intl-unofficial-duration-unit-format": "^3.1.0" }, "devDependencies": { "@babel/eslint-parser": "^7.18.2", diff --git a/addons/core/tests/integration/helpers/format-time-duration-test.js b/addons/core/tests/integration/helpers/format-time-duration-test.js new file mode 100644 index 000000000..66eabaca2 --- /dev/null +++ b/addons/core/tests/integration/helpers/format-time-duration-test.js @@ -0,0 +1,30 @@ +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'dummy/tests/helpers'; +import { render } from '@ember/test-helpers'; +import { hbs } from 'ember-cli-htmlbars'; +import { setupIntl } from 'ember-intl/test-support'; + +module('Integration | Helper | format-time-duration', function (hooks) { + setupRenderingTest(hooks); + setupIntl(hooks); + + test('It renders in human-readable duration strings given different durations in milliseconds', async function (assert) { + // Set mock input (in milliseconds) durations + this.set('inputDurationSeconds', 3000); + this.set('inputDurationMinutes', 2700000); + this.set('inputDurationHours', 5000000); + this.set('inputDurationDays', 177800000); + + await render(hbs`{{format-time-duration this.inputDurationSeconds}}`); + assert.dom(this.element).hasText('3 sec'); + + await render(hbs`{{format-time-duration this.inputDurationMinutes}}`); + assert.dom(this.element).hasText('45 min'); + + await render(hbs`{{format-time-duration this.inputDurationHours}}`); + assert.dom(this.element).hasText('1 hr 23 min 20 sec'); + + await render(hbs`{{format-time-duration this.inputDurationDays}}`); + assert.dom(this.element).hasText('2 days 1 hr 23 min 20 sec'); + }); +}); diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs index 1ce0230e6..e6b42053c 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs @@ -10,5 +10,11 @@ > {{@model.session_recording_id}} +

+

{{format-time-duration 3000}}

+

{{format-time-duration 2700000}}

+

{{format-time-duration 5000000}}

+

{{format-time-duration 177800000}}

+ {{!--

{{format-time-duration 177800000}}

--}} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 094a5753d..aebf9d8ae 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10551,9 +10551,9 @@ caniuse-api@^3.0.0: lodash.uniq "^4.5.0" caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001157, caniuse-lite@^1.0.30001449: - version "1.0.30001458" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001458.tgz#871e35866b4654a7d25eccca86864f411825540c" - integrity sha512-lQ1VlUUq5q9ro9X+5gOEyH7i3vm+AYVT1WDCVB69XOZ17KZRhnZ9J0Sqz7wTHQaLBJccNCHq8/Ww5LlOIZbB0w== + version "1.0.30001466" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001466.tgz#c1e6197c540392e09709ecaa9e3e403428c53375" + integrity sha512-ewtFBSfWjEmxUgNBSZItFSmVtvk9zkwkl1OfRZlKA8slltRN+/C/tuGVrF9styXkN36Yu3+SeJ1qkXxDEyNZ5w== capture-exit@^2.0.0: version "2.0.0" @@ -11905,7 +11905,7 @@ debug@^3.0.0, debug@^3.0.1, debug@^3.1.0, debug@^3.1.1, debug@^3.2.7: dependencies: ms "^2.1.1" -debuglog@^1.0.1: +debuglog@*, debuglog@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" integrity sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI= @@ -17097,7 +17097,7 @@ import-local@^3.0.2: pkg-dir "^4.2.0" resolve-cwd "^3.0.0" -imurmurhash@^0.1.4: +imurmurhash@*, imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= @@ -17269,6 +17269,11 @@ intl-messageformat@10.2.1, intl-messageformat@^10.1.0: "@formatjs/icu-messageformat-parser" "2.1.10" tslib "2.4.0" +intl-unofficial-duration-unit-format@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/intl-unofficial-duration-unit-format/-/intl-unofficial-duration-unit-format-3.1.0.tgz#994feefc8d903d9e5044dc7e4e1d38ebad59394b" + integrity sha512-yjvUDwV63zSGkbeUqpDRJmOgMQoJA8OFhNeo+1KY20q+lFCtcvRWszJNsq/ssrUJRy8g+Mt3BYNfwFvRRSAkow== + invariant@^2.2.2, invariant@^2.2.3, invariant@^2.2.4: version "2.2.4" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" @@ -19228,6 +19233,11 @@ lodash._baseflatten@^3.0.0: lodash.isarguments "^3.0.0" lodash.isarray "^3.0.0" +lodash._baseindexof@*: + version "3.1.0" + resolved "https://registry.yarnpkg.com/lodash._baseindexof/-/lodash._baseindexof-3.1.0.tgz#fe52b53a1c6761e42618d654e4a25789ed61822c" + integrity sha512-bSYo8Pc/f0qAkr8fPJydpJjtrHiSynYfYBjtANIgXv5xEf1WlTC63dIDlgu0s9dmTvzRu1+JJTxcIAHe+sH0FQ== + lodash._baseuniq@~4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash._baseuniq/-/lodash._baseuniq-4.6.0.tgz#0ebb44e456814af7905c6212fa2c9b2d51b841e8" @@ -19236,11 +19246,16 @@ lodash._baseuniq@~4.6.0: lodash._createset "~4.0.0" lodash._root "~3.0.0" -lodash._bindcallback@^3.0.0: +lodash._bindcallback@*, lodash._bindcallback@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz#e531c27644cf8b57a99e17ed95b35c748789392e" integrity sha512-2wlI0JRAGX8WEf4Gm1p/mv/SZ+jLijpj0jyaE/AXeuQphzCgD8ZQW4oSpoN8JAopujOFGU3KMuq7qfHBWlGpjQ== +lodash._cacheindexof@*: + version "3.0.2" + resolved "https://registry.yarnpkg.com/lodash._cacheindexof/-/lodash._cacheindexof-3.0.2.tgz#3dc69ac82498d2ee5e3ce56091bafd2adc7bde92" + integrity sha512-S8dUjWr7SUT/X6TBIQ/OYoCHo1Stu1ZRy6uMUSKqzFnZp5G5RyQizSm6kvxD2Ewyy6AVfMg4AToeZzKfF99T5w== + lodash._createassigner@^3.0.0: version "3.1.1" resolved "https://registry.yarnpkg.com/lodash._createassigner/-/lodash._createassigner-3.1.1.tgz#838a5bae2fdaca63ac22dee8e19fa4e6d6970b11" @@ -19250,12 +19265,19 @@ lodash._createassigner@^3.0.0: lodash._isiterateecall "^3.0.0" lodash.restparam "^3.0.0" +lodash._createcache@*: + version "3.1.2" + resolved "https://registry.yarnpkg.com/lodash._createcache/-/lodash._createcache-3.1.2.tgz#56d6a064017625e79ebca6b8018e17440bdcf093" + integrity sha512-ev5SP+iFpZOugyab/DEUQxUeZP5qyciVTlgQ1f4Vlw7VUcCD8fVnyIqVUEIaoFH9zjAqdgi69KiofzvVmda/ZQ== + dependencies: + lodash._getnative "^3.0.0" + lodash._createset@~4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/lodash._createset/-/lodash._createset-4.0.3.tgz#0f4659fbb09d75194fa9e2b88a6644d363c9fe26" integrity sha512-GTkC6YMprrJZCYU3zcqZj+jkXkrXzq3IPBcF/fIPpNEAB4hZEtXU8zp/RwKOvZl43NUmwDbyRk3+ZTbeRdEBXA== -lodash._getnative@^3.0.0: +lodash._getnative@*, lodash._getnative@^3.0.0: version "3.9.1" resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" integrity sha512-RrL9VxMEPyDMHOd9uFbvMe8X55X16/cGM5IgOKgRElQZutpX89iS6vwl64duTV1/16w5JY7tuFNXqoekmh1EmA== @@ -19468,7 +19490,7 @@ lodash.pick@^4.4.0: resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3" integrity sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q== -lodash.restparam@^3.0.0: +lodash.restparam@*, lodash.restparam@^3.0.0: version "3.6.1" resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" integrity sha512-L4/arjjuq4noiUJpt3yS6KIKDtJwNe2fIYgMqyYYKoeIfV1iEqvPwhCx23o+R9dzouGihDAPN1dTIRWa7zk8tw== @@ -25706,9 +25728,9 @@ terser-webpack-plugin@^5.1.3: terser "^5.7.2" terser@^4.1.2, terser@^4.6.3, terser@^5.14.2, terser@^5.3.0, terser@^5.3.4, terser@^5.7.2: - version "5.16.5" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.16.5.tgz#1c285ca0655f467f92af1bbab46ab72d1cb08e5a" - integrity sha512-qcwfg4+RZa3YvlFh0qjifnzBHjKGNbtDo9yivMqMFDy9Q6FSaQWSB/j1xKhsoUFJIqDOM3TsN6D5xbrMrFcHbg== + version "5.16.6" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.16.6.tgz#f6c7a14a378ee0630fbe3ac8d1f41b4681109533" + integrity sha512-IBZ+ZQIA9sMaXmRZCUMDjNH0D5AQQfdn4WUjHL0+1lF4TP1IHRJbrhb6fNaXWikrYQTSkb7SLxkeXAiy1p7mbg== dependencies: "@jridgewell/source-map" "^0.3.2" acorn "^8.5.0" From 7782739d2d46900440c4c024576cd36f615d3fa6 Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Date: Tue, 14 Mar 2023 12:28:54 -0700 Subject: [PATCH 038/193] Change durationUnitFormat style from short to narrow --- addons/core/addon/helpers/format-time-duration.js | 2 +- .../app/templates/scopes/scope/session-recordings/index.hbs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/addons/core/addon/helpers/format-time-duration.js b/addons/core/addon/helpers/format-time-duration.js index bf3e3efe8..5477b5b40 100644 --- a/addons/core/addon/helpers/format-time-duration.js +++ b/addons/core/addon/helpers/format-time-duration.js @@ -15,7 +15,7 @@ export default class extends Helper { compute([durationInMs]) { const durationInSeconds = durationInMs / 1000; const durationFormat = new DurationUnitFormat(this.intl.primaryLocale, { - style: 'short', + style: 'narrow', format: '{days} {hours} {minutes} {seconds}', round: true, }); diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs index e6b42053c..c0a36d055 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs @@ -15,6 +15,5 @@

{{format-time-duration 2700000}}

{{format-time-duration 5000000}}

{{format-time-duration 177800000}}

- {{!--

{{format-time-duration 177800000}}

--}} \ No newline at end of file From e0a595c9ecf90586c6c2040275c1b9e45dd3115f Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Date: Tue, 14 Mar 2023 12:41:43 -0700 Subject: [PATCH 039/193] Update test with new format --- .../integration/helpers/format-time-duration-test.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/addons/core/tests/integration/helpers/format-time-duration-test.js b/addons/core/tests/integration/helpers/format-time-duration-test.js index 66eabaca2..7efa7adb9 100644 --- a/addons/core/tests/integration/helpers/format-time-duration-test.js +++ b/addons/core/tests/integration/helpers/format-time-duration-test.js @@ -16,15 +16,15 @@ module('Integration | Helper | format-time-duration', function (hooks) { this.set('inputDurationDays', 177800000); await render(hbs`{{format-time-duration this.inputDurationSeconds}}`); - assert.dom(this.element).hasText('3 sec'); + assert.dom(this.element).hasText('3s'); await render(hbs`{{format-time-duration this.inputDurationMinutes}}`); - assert.dom(this.element).hasText('45 min'); + assert.dom(this.element).hasText('45m'); await render(hbs`{{format-time-duration this.inputDurationHours}}`); - assert.dom(this.element).hasText('1 hr 23 min 20 sec'); + assert.dom(this.element).hasText('1h 23m 20s'); await render(hbs`{{format-time-duration this.inputDurationDays}}`); - assert.dom(this.element).hasText('2 days 1 hr 23 min 20 sec'); + assert.dom(this.element).hasText('2d 1h 23m 20s'); }); }); From 826a565a81590c541427879a9f9609cc94806548 Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Date: Tue, 14 Mar 2023 14:37:41 -0700 Subject: [PATCH 040/193] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20Use=20mirage=20d?= =?UTF-8?q?ata=20for=20simple=20navigation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use provided mirage data for simple navigation from the list of session recordings to a detailed channel within a connection --- addons/core/translations/resources/en-us.yaml | 3 +++ .../routes/scopes/scope/session-recordings.js | 9 +++---- .../session-recordings/session-recording.js | 20 ++++++++++---- .../channels-by-connection/channel.js | 9 +++++-- .../scopes/scope/session-recordings/index.hbs | 16 ++++++----- .../channels-by-connection/channel.hbs | 2 +- .../session-recording/index.hbs | 27 ++++++++++--------- 7 files changed, 54 insertions(+), 32 deletions(-) diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml index cb5ae2fc4..3e6ee2b6b 100644 --- a/addons/core/translations/resources/en-us.yaml +++ b/addons/core/translations/resources/en-us.yaml @@ -214,6 +214,9 @@ org: session-recording: title: Session Recording title_plural: Session Recordings + connection: + title: Connection + title_plural: Connections channel: title: Channel title_plural: Channels diff --git a/ui/admin/app/routes/scopes/scope/session-recordings.js b/ui/admin/app/routes/scopes/scope/session-recordings.js index efffa07f1..d7dc6b09c 100644 --- a/ui/admin/app/routes/scopes/scope/session-recordings.js +++ b/ui/admin/app/routes/scopes/scope/session-recordings.js @@ -24,14 +24,11 @@ export default class ScopesScopeSessionRecordingsRoute extends Route { */ model() { // TODO: awaiting modeled data - // const scope = this.modelFor('scopes.scope'); - // const { id: scope_id } = scope; + const scope = this.modelFor('scopes.scope'); + const { id: scope_id } = scope; // if (this.can.can('list session-recording', scope, { collection: 'session-recordings' })) { - // return this.store.query('session-recording', { scope_id }); + return this.store.query('recording', { scope_id }); // } - return { - session_recording_id: 'sr_1234567890', - }; } // =actions diff --git a/ui/admin/app/routes/scopes/scope/session-recordings/session-recording.js b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording.js index eda72d65e..e09ebbfc8 100644 --- a/ui/admin/app/routes/scopes/scope/session-recordings/session-recording.js +++ b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording.js @@ -1,12 +1,22 @@ import Route from '@ember/routing/route'; +import { inject as service } from '@ember/service'; export default class ScopesScopeSessionRecordingsSessionRecordingRoute extends Route { // =services + @service store; + @service session; + @service router; + // =methods - model() { - return { - session_recording_id: 'sr_1234567890', - channel_connection_id: 'srcc_1234567890', - }; + + /** + * If arriving here unauthenticated, redirect to index for further processing. + */ + beforeModel() { + if (!this.session.isAuthenticated) this.router.transitionTo('index'); + } + + async model({ session_recording_id }) { + return this.store.findRecord('recording', session_recording_id); } } diff --git a/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.js b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.js index 494ee45e6..037f8ee20 100644 --- a/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.js +++ b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.js @@ -1,12 +1,17 @@ import Route from '@ember/routing/route'; +import { inject as service } from '@ember/service'; export default class ScopesScopeSessionRecordingsSessionRecordingChannelsByConnectionChannelRoute extends Route { - async model() { + // =services + @service store; + + // =methods + async model({ channel_id }) { const response = await fetch('/session.cast'); const asciicast = await response.text(); return { - scope_id: 'srcc_1234567890', + channel_id: channel_id, asciicast: asciicast, }; } diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs index 1ce0230e6..5762bc212 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs @@ -4,11 +4,15 @@ - - {{@model.session_recording_id}} - + {{#each @model as |recording|}} +

+ + {{recording.id}} + +

+ {{/each}}
\ No newline at end of file diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs index 015c8a546..f36440b2a 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs @@ -12,7 +12,7 @@ -

{{@model.scope_id}}

+

{{@model.channel_id}}

diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs index 4bdc99323..0100fa33a 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs @@ -8,20 +8,23 @@

{{t 'resources.session-recording.title'}} - {{@model.session_recording_id}} + {{@model.id}}

-

- {{t 'resources.session-recording.channel.title'}} - {{@model.channel_connection_id}} -

- - - {{@model.channel_connection_id}} - + {{#each @model.connections as |connection|}} +

{{t 'resources.session-recording.connection.title'}} + {{connection.id}}

+ {{#each connection.channels as |channel|}} +

+ + {{channel.id}} + +

+ {{/each}} + {{/each}}
From a28e7810e714fd0ca9e3d2bbf49526556ac5b7e2 Mon Sep 17 00:00:00 2001 From: Devon Anderson Date: Wed, 15 Mar 2023 12:23:14 -0400 Subject: [PATCH 041/193] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20add=20edit=20fun?= =?UTF-8?q?ctionality=20to=20list=20item=20for=20storage=20bucket=20(#116)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 🎸 add edit functionality to list item for storage bucket Add edit option which navigates to the storage bucket details view. βœ… Closes: ICU-8228 * refactor: πŸ’‘ refactor styling for dropdown Pushed some override stylings into `overrides.scss` in addon styles. βœ… Closes: ICU-8228 * refactor: πŸ’‘ commit to validate not box-shadow withouth override This is just a commit to show a vercel view of dropdown without overrides. βœ… Closes: ICU-8228 * refactor: πŸ’‘ refactor hds themes Added `light-mode` mixin to the `.ember-application.rose-theme-light` selector to fix missing `box-shadow` colors. βœ… Closes: ICU-8228 --- addons/rose/addon/styles/hds/overrides.scss | 10 ++++++++++ .../addon/styles/hds/themes/dark-mode/index.scss | 5 +++++ ui/admin/app/styles/app.scss | 4 ---- .../scopes/scope/storage-buckets/index.hbs | 16 ++++++++++++++-- 4 files changed, 29 insertions(+), 6 deletions(-) diff --git a/addons/rose/addon/styles/hds/overrides.scss b/addons/rose/addon/styles/hds/overrides.scss index e59e492ee..6fb85c777 100644 --- a/addons/rose/addon/styles/hds/overrides.scss +++ b/addons/rose/addon/styles/hds/overrides.scss @@ -16,3 +16,13 @@ } } } + +.hds-table { + border-collapse: revert; +} + +.hds-dropdown { + .hds-dropdown-toggle-icon { + color: inherit; + } +} diff --git a/addons/rose/addon/styles/hds/themes/dark-mode/index.scss b/addons/rose/addon/styles/hds/themes/dark-mode/index.scss index 4d06786ff..59e78d8b3 100644 --- a/addons/rose/addon/styles/hds/themes/dark-mode/index.scss +++ b/addons/rose/addon/styles/hds/themes/dark-mode/index.scss @@ -104,6 +104,11 @@ --token-color-palette-neutral-500-alpha-50: #656a760d; } +.ember-application, +.ember-application.rose-theme-light { + @include light-mode; +} + @media (prefers-color-scheme: dark) { .ember-application:not(.rose-theme-light) { @include dark-mode; diff --git a/ui/admin/app/styles/app.scss b/ui/admin/app/styles/app.scss index f71bcf07e..c1bc62db0 100644 --- a/ui/admin/app/styles/app.scss +++ b/ui/admin/app/styles/app.scss @@ -776,7 +776,3 @@ 'sidebar'; } } - -.storage-bucket-list { - border-collapse: revert; -} diff --git a/ui/admin/app/templates/scopes/scope/storage-buckets/index.hbs b/ui/admin/app/templates/scopes/scope/storage-buckets/index.hbs index 082c294eb..01c093f4c 100644 --- a/ui/admin/app/templates/scopes/scope/storage-buckets/index.hbs +++ b/ui/admin/app/templates/scopes/scope/storage-buckets/index.hbs @@ -32,7 +32,6 @@ {{#if @model}} - {{!TODO: add dropdown for delete and edit actions}} + {{!TODO: add dropdown for delete actions}} + + + + From 5992829fa2ab7e43cd7179ad8698cd76f212cc0e Mon Sep 17 00:00:00 2001 From: Zhihe Li Date: Wed, 15 Mar 2023 15:18:02 -0400 Subject: [PATCH 042/193] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20Add=20serializer?= =?UTF-8?q?=20and=20adapter=20for=20storage=20bucket=20(#117)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 🎸 Add serializer and adapter for storage bucket βœ… Closes: ICU-8358 --- addons/api/addon/adapters/storage-bucket.js | 23 +++++ .../addon/generated/models/storage-bucket.js | 2 +- .../api/addon/serializers/storage-bucket.js | 13 +++ addons/api/app/adapters/storage-bucket.js | 1 + addons/api/app/serializers/storage-bucket.js | 1 + addons/api/mirage/config.js | 8 +- .../unit/adapters/storage-bucket-test.js | 30 ++++++ .../unit/serializers/storage-bucket-test.js | 99 +++++++++++++++++++ 8 files changed, 175 insertions(+), 2 deletions(-) create mode 100644 addons/api/addon/adapters/storage-bucket.js create mode 100644 addons/api/addon/serializers/storage-bucket.js create mode 100644 addons/api/app/adapters/storage-bucket.js create mode 100644 addons/api/app/serializers/storage-bucket.js create mode 100644 addons/api/tests/unit/adapters/storage-bucket-test.js create mode 100644 addons/api/tests/unit/serializers/storage-bucket-test.js diff --git a/addons/api/addon/adapters/storage-bucket.js b/addons/api/addon/adapters/storage-bucket.js new file mode 100644 index 000000000..4f72f57a2 --- /dev/null +++ b/addons/api/addon/adapters/storage-bucket.js @@ -0,0 +1,23 @@ +import ApplicationAdapter from './application'; + +export default class StorageBucketAdapter extends ApplicationAdapter { + /** + * Overrides the default `buildURL` such that on _create_, URLs for records of + * type `plugin` get an extra query parameter `?plugin_name`. All other + * request types behave as normal. + * + * @override + * @param {string} modelName + * @param {string} id + * @return {string} url + * @return {string} requestType + */ + buildURL(modelName, id, snapshot, requestType) { + let url = super.buildURL(...arguments); + const pluginName = snapshot?.attr('plugin')?.name; + if (requestType === 'createRecord' && pluginName) { + url = `${url}?plugin_name=${pluginName}`; + } + return url; + } +} diff --git a/addons/api/addon/generated/models/storage-bucket.js b/addons/api/addon/generated/models/storage-bucket.js index 6423d33ee..d81c1ade7 100644 --- a/addons/api/addon/generated/models/storage-bucket.js +++ b/addons/api/addon/generated/models/storage-bucket.js @@ -72,7 +72,7 @@ export default class GeneratedStorageBucketModel extends BaseModel { readOnly: true, isNestedAttribute: true, }) - client_secret_hmac; + secrets_hmac; @attr('string', { isNestedSecret: true, diff --git a/addons/api/addon/serializers/storage-bucket.js b/addons/api/addon/serializers/storage-bucket.js new file mode 100644 index 000000000..ae8e818d5 --- /dev/null +++ b/addons/api/addon/serializers/storage-bucket.js @@ -0,0 +1,13 @@ +import ApplicationSerializer from './application'; + +export default class StorageBucketSerializer extends ApplicationSerializer { + normalize(typeClass, hash, ...rest) { + const normalizedHash = structuredClone(hash); + const normalized = super.normalize(typeClass, normalizedHash, ...rest); + + // Remove secret fields + delete normalized.data.attributes.access_key_id; + delete normalized.data.attributes.secret_access_key; + return normalized; + } +} diff --git a/addons/api/app/adapters/storage-bucket.js b/addons/api/app/adapters/storage-bucket.js new file mode 100644 index 000000000..ceadb4e71 --- /dev/null +++ b/addons/api/app/adapters/storage-bucket.js @@ -0,0 +1 @@ +export { default } from 'api/adapters/storage-bucket'; diff --git a/addons/api/app/serializers/storage-bucket.js b/addons/api/app/serializers/storage-bucket.js new file mode 100644 index 000000000..b17b78a70 --- /dev/null +++ b/addons/api/app/serializers/storage-bucket.js @@ -0,0 +1 @@ +export { default } from 'api/serializers/storage-bucket'; diff --git a/addons/api/mirage/config.js b/addons/api/mirage/config.js index 62041703a..648229604 100644 --- a/addons/api/mirage/config.js +++ b/addons/api/mirage/config.js @@ -14,6 +14,7 @@ import { targetHandler } from './route-handlers/target'; import { pickRandomStatusString } from './factories/session'; import initializeMockIPC from './scenarios/ipc'; import makeBooleanFilter from './helpers/bexpr-filter'; +import { faker } from '@faker-js/faker'; const isTesting = environmentConfig.environment === 'test'; @@ -668,7 +669,7 @@ function routes() { this.patch('/storage-buckets/:id'); this.post( '/storage-buckets', - ({ storageBuckets }, { queryParams: { plugin_name } }) => { + function ({ storageBuckets }, { queryParams: { plugin_name } }) { const attrs = this.normalizedRequestAttrs(); if (plugin_name) { attrs.type = 'plugin'; @@ -676,6 +677,11 @@ function routes() { name: plugin_name, }; } + + // Remove the secrets and add the hmac in the response + delete attrs.secrets; + attrs.secrets_hmac = faker.git.commitSha(); + return storageBuckets.create(attrs); } ); diff --git a/addons/api/tests/unit/adapters/storage-bucket-test.js b/addons/api/tests/unit/adapters/storage-bucket-test.js new file mode 100644 index 000000000..dcfdfa83f --- /dev/null +++ b/addons/api/tests/unit/adapters/storage-bucket-test.js @@ -0,0 +1,30 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Adapter | storage bucket', function (hooks) { + setupTest(hooks); + + test('it generates correct createRecord URLs for storage buckets with extra query parameter ?plugin_name', function (assert) { + assert.expect(1); + const scopeID = 'o_1'; + const mockSnapshot = { + adapterOptions: { + scopeID, + }, + attr() { + return { name: 'aws_s3' }; + }, + }; + const adapter = this.owner.lookup('adapter:storage-bucket'); + const createRecordURL = adapter.buildURL( + 'storage-bucket', + null, + mockSnapshot, + 'createRecord' + ); + assert.strictEqual( + createRecordURL, + '/v1/storage-buckets?plugin_name=aws_s3' + ); + }); +}); diff --git a/addons/api/tests/unit/serializers/storage-bucket-test.js b/addons/api/tests/unit/serializers/storage-bucket-test.js new file mode 100644 index 000000000..d3fa6dab6 --- /dev/null +++ b/addons/api/tests/unit/serializers/storage-bucket-test.js @@ -0,0 +1,99 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; +import { + TYPE_STORAGE_BUCKET_PLUGIN_AWS_S3, + TYPE_STORAGE_BUCKET_PLUGIN, +} from 'api/models/storage-bucket'; + +module('Unit | Serializer | storage bucket', function (hooks) { + setupTest(hooks); + + test('it serializes records', function (assert) { + let store = this.owner.lookup('service:store'); + let record = store.createRecord('storage-bucket', {}); + + let serializedRecord = record.serialize(); + + assert.ok(serializedRecord); + }); + + test('it serializes a new aws plugin as expected', async function (assert) { + assert.expect(1); + const store = this.owner.lookup('service:store'); + const record = store.createRecord('storage-bucket', { + compositeType: TYPE_STORAGE_BUCKET_PLUGIN_AWS_S3, + name: 'AWS', + description: 'this has an aws plugin', + bucket_name: 'bucketname', + bucket_prefix: 'bucketprefix', + worker_filter: 'workerfilter', + region: 'eu-west-1', + access_key_id: 'foobars', + secret_access_key: 'testing', + secrets_hmac: 'hmac', + }); + const expectedResult = { + name: 'AWS', + description: 'this has an aws plugin', + type: TYPE_STORAGE_BUCKET_PLUGIN, + bucket_name: 'bucketname', + bucket_prefix: 'bucketprefix', + worker_filter: 'workerfilter', + attributes: { + region: 'eu-west-1', + }, + secrets: { + access_key_id: 'foobars', + secret_access_key: 'testing', + }, + }; + assert.deepEqual(record.serialize(), expectedResult); + }); + + test('it normalizes correctly', function (assert) { + assert.expect(1); + const store = this.owner.lookup('service:store'); + const serializer = store.serializerFor('storage-bucket'); + const hostSetModelClass = store.createRecord('storage-bucket').constructor; + const payload = { + id: '1', + version: 1, + name: 'AWS', + description: 'this has an aws plugin', + type: TYPE_STORAGE_BUCKET_PLUGIN, + bucket_name: 'bucketname', + bucket_prefix: 'bucketprefix', + worker_filter: 'workerfilter', + attributes: { + region: 'eu-west-1', + }, + secrets_hmac: 'this is secret', + }; + const normalized = serializer.normalizeSingleResponse( + store, + hostSetModelClass, + payload + ); + + assert.deepEqual(normalized, { + included: [], + data: { + id: '1', + attributes: { + type: TYPE_STORAGE_BUCKET_PLUGIN, + version: 1, + authorized_actions: [], + name: 'AWS', + description: 'this has an aws plugin', + bucket_name: 'bucketname', + bucket_prefix: 'bucketprefix', + worker_filter: 'workerfilter', + secrets_hmac: 'this is secret', + region: 'eu-west-1', + }, + type: 'storage-bucket', + relationships: {}, + }, + }); + }); +}); From bf2029eb54229c8fa26c6f924575ccc7852ea3f0 Mon Sep 17 00:00:00 2001 From: Zhihe Li Date: Wed, 15 Mar 2023 15:45:51 -0400 Subject: [PATCH 043/193] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20Add=20abilities?= =?UTF-8?q?=20for=20session=20recordings=20(#120)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 🎸 Add abilities for session recordings βœ… Closes: ICU-8079 --- addons/api/addon/abilities/recording.js | 34 +++ addons/api/app/abilities/recording.js | 3 + addons/api/mirage/factories/recording.js | 6 +- addons/api/mirage/factories/scope.js | 2 + ui/admin/app/abilities/recording.js | 33 +++ ui/admin/app/abilities/storage-bucket.js | 7 +- .../tests/unit/abilities/recording-test.js | 221 ++++++++++++++++++ .../unit/abilities/storage-bucket-test.js | 45 ++-- 8 files changed, 324 insertions(+), 27 deletions(-) create mode 100644 addons/api/addon/abilities/recording.js create mode 100644 addons/api/app/abilities/recording.js create mode 100644 ui/admin/app/abilities/recording.js create mode 100644 ui/admin/tests/unit/abilities/recording-test.js diff --git a/addons/api/addon/abilities/recording.js b/addons/api/addon/abilities/recording.js new file mode 100644 index 000000000..7d9da0957 --- /dev/null +++ b/addons/api/addon/abilities/recording.js @@ -0,0 +1,34 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import ModelAbility from './model'; + +/** + * Provides abilities for session recordings. + */ +export default class RecordingAbility extends ModelAbility { + // =services + + // =permissions + + /** + * Only "known" session recording types may be read. + * @type {boolean} + */ + get canRead() { + return !this.model.isUnknown && this.hasAuthorizedAction('read'); + } + + get canList() { + return ( + this.hasAuthorizedCollectionAction('list') && + (this.model.isGlobal || this.model.isOrg) + ); + } + + get canDownloadAsciiCast() { + return this.model.isSSH && this.hasAuthorizedAction('download'); + } +} diff --git a/addons/api/app/abilities/recording.js b/addons/api/app/abilities/recording.js new file mode 100644 index 000000000..a6d654ffd --- /dev/null +++ b/addons/api/app/abilities/recording.js @@ -0,0 +1,3 @@ +import { Ability } from 'ember-can'; + +export default class extends Ability {} diff --git a/addons/api/mirage/factories/recording.js b/addons/api/mirage/factories/recording.js index 1c39abf09..ce2cf9c99 100644 --- a/addons/api/mirage/factories/recording.js +++ b/addons/api/mirage/factories/recording.js @@ -18,7 +18,11 @@ export default factory.extend({ type: (i) => types[i % types.length], authorized_actions: () => - permissions.authorizedActionsFor('recording') || ['no-op', 'read', 'list'], + permissions.authorizedActionsFor('recording') || [ + 'no-op', + 'read', + 'download', + ], withNonExistingUserAndTarget: trait({ afterCreate(recording, server) { diff --git a/addons/api/mirage/factories/scope.js b/addons/api/mirage/factories/scope.js index a61f252ee..568efe1df 100644 --- a/addons/api/mirage/factories/scope.js +++ b/addons/api/mirage/factories/scope.js @@ -37,8 +37,10 @@ export default factory.extend({ collectionActions.workers = ['create:worker-led', 'list']; } + // Session recording resources are only available on global or org scope if (this.type === 'global' || this.type === 'org') { collectionActions['storage-buckets'] = ['create', 'list']; + collectionActions.recordings = ['list']; } return collectionActions; diff --git a/ui/admin/app/abilities/recording.js b/ui/admin/app/abilities/recording.js new file mode 100644 index 000000000..3365397c8 --- /dev/null +++ b/ui/admin/app/abilities/recording.js @@ -0,0 +1,33 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import RecordingAbility from 'api/abilities/recording'; +import { inject as service } from '@ember/service'; + +export default class OverrideRecordingAbility extends RecordingAbility { + // =service + @service features; + + /** + * This override ensures that session recordings may be read only if the + * session-recording feature flag is enabled. + */ + get canRead() { + return this.features.isEnabled('session-recording') ? super.canRead : false; + } + + /** + * This override ensures that session recordings can only be presented in the global scope + * and if the session-recording feature flag is enabled. */ + get canList() { + return this.features.isEnabled('session-recording') + ? this.hasAuthorizedCollectionAction('list') && this.model.isGlobal + : false; + } + + get canNavigate() { + return this.canList; + } +} diff --git a/ui/admin/app/abilities/storage-bucket.js b/ui/admin/app/abilities/storage-bucket.js index a34d0b9d3..c8fae92d6 100644 --- a/ui/admin/app/abilities/storage-bucket.js +++ b/ui/admin/app/abilities/storage-bucket.js @@ -19,10 +19,13 @@ export default class OverrideStorageBucketAbility extends StorageBucketAbility { } /** - * This override ensures that storage buckets can only be presented in the global scope. + * This override ensures that storage buckets can only be presented in the global scope + * and if the session-recording feature flag is enabled. */ get canList() { - return this.hasAuthorizedCollectionAction('list') && this.model.isGlobal; + return this.features.isEnabled('session-recording') + ? this.hasAuthorizedCollectionAction('list') && this.model.isGlobal + : false; } get canNavigate() { diff --git a/ui/admin/tests/unit/abilities/recording-test.js b/ui/admin/tests/unit/abilities/recording-test.js new file mode 100644 index 000000000..05a46b2b5 --- /dev/null +++ b/ui/admin/tests/unit/abilities/recording-test.js @@ -0,0 +1,221 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; +import { TYPE_RECORDING_SSH } from 'api/models/recording'; + +module('Unit | Abilities | session-recording', function (hooks) { + setupTest(hooks); + + let features; + let canService; + let store; + + hooks.beforeEach(function () { + features = this.owner.lookup('service:features'); + features.enable('session-recording'); + canService = this.owner.lookup('service:can'); + store = this.owner.lookup('service:store'); + }); + + test('can read session recording feature is enabled', function (assert) { + assert.expect(2); + + const recordingWithAuthorizedAction = store.createRecord('recording', { + authorized_actions: ['read'], + type: TYPE_RECORDING_SSH, + }); + const recordingWithoutAuthorizedAction = store.createRecord('recording', { + authorized_actions: [], + type: TYPE_RECORDING_SSH, + }); + + assert.true( + canService.can('read recording', recordingWithAuthorizedAction) + ); + assert.false( + canService.can('read recording', recordingWithoutAuthorizedAction) + ); + }); + + test('cannot read session recording when feature is disabled', function (assert) { + assert.expect(2); + features.disable('session-recording'); + + const recordingWithAuthorizedAction = store.createRecord('recording', { + authorized_actions: ['read'], + type: TYPE_RECORDING_SSH, + }); + const recordingWithoutAuthorizedAction = store.createRecord('recording', { + authorized_actions: [], + type: TYPE_RECORDING_SSH, + }); + + assert.false( + canService.can('read recording', recordingWithAuthorizedAction) + ); + assert.false( + canService.can('read recording', recordingWithoutAuthorizedAction) + ); + }); + + test('can list session recording when in global scope', function (assert) { + assert.expect(2); + + const scopeModelWithAuthorizedAction = store.createRecord('scope', { + authorized_collection_actions: { recordings: ['list'] }, + type: 'global', + id: 'first', + }); + const scopeModelWithoutAuthorizedAction = store.createRecord('scope', { + authorized_collection_actions: { recordings: [] }, + type: 'global', + id: 'second', + }); + + assert.true( + canService.can('list recording', scopeModelWithAuthorizedAction, { + collection: 'recordings', + }) + ); + assert.false( + canService.can('list recording', scopeModelWithoutAuthorizedAction, { + collection: 'recordings', + }) + ); + }); + + test('cannot list session recording when in org scope', function (assert) { + assert.expect(2); + + const scopeModelWithAuthorizedAction = store.createRecord('scope', { + authorized_collection_actions: { recordings: ['list'] }, + type: 'org', + id: 'first', + }); + const scopeModelWithoutAuthorizedAction = store.createRecord('scope', { + authorized_collection_actions: { recordings: [] }, + type: 'org', + id: 'second', + }); + + assert.false( + canService.can('list recording', scopeModelWithAuthorizedAction, { + collection: 'recordings', + }) + ); + assert.false( + canService.can('list recording', scopeModelWithoutAuthorizedAction, { + collection: 'recordings', + }) + ); + }); + + test('can navigate to session recording when feature is enabled', function (assert) { + assert.expect(2); + + const scopeModelWithAuthorizedAction = store.createRecord('scope', { + authorized_collection_actions: { recordings: ['list'] }, + type: 'global', + id: 'first', + }); + const scopeModelWithoutAuthorizedAction = store.createRecord('scope', { + authorized_collection_actions: { recordings: [] }, + type: 'global', + id: 'second', + }); + + assert.true( + canService.can('navigate recording', scopeModelWithAuthorizedAction, { + collection: 'recordings', + }) + ); + assert.false( + canService.can('navigate recording', scopeModelWithoutAuthorizedAction, { + collection: 'recordings', + }) + ); + }); + + test('cannot navigate to session recording when feature is disabled', function (assert) { + assert.expect(2); + features.disable('session-recording'); + + const scopeModelWithAuthorizedAction = store.createRecord('scope', { + authorized_collection_actions: { recordings: ['list'] }, + type: 'global', + id: 'first', + }); + const scopeModelWithoutAuthorizedAction = store.createRecord('scope', { + authorized_collection_actions: { recordings: [] }, + type: 'global', + id: 'second', + }); + + assert.false( + canService.can('navigate recording', scopeModelWithAuthorizedAction, { + collection: 'recordings', + }) + ); + assert.false( + canService.can('navigate recording', scopeModelWithoutAuthorizedAction, { + collection: 'recordings', + }) + ); + }); + + test('can download asciicast when an ssh recording has download authorization', function (assert) { + assert.expect(2); + + const recordingWithAuthorizedAction = store.createRecord('recording', { + authorized_actions: ['download'], + type: TYPE_RECORDING_SSH, + }); + const recordingWithoutAuthorizedAction = store.createRecord('recording', { + authorized_actions: [], + type: TYPE_RECORDING_SSH, + }); + + assert.true( + canService.can( + 'downloadAsciiCast recording', + recordingWithAuthorizedAction + ) + ); + assert.false( + canService.can( + 'downloadAsciiCast recording', + recordingWithoutAuthorizedAction + ) + ); + }); + + test('cannot download asciicast when a recording is not ssh type', function (assert) { + assert.expect(2); + + const recordingWithAuthorizedAction = store.createRecord('recording', { + authorized_actions: ['download'], + type: 'unknown', + }); + const recordingWithoutAuthorizedAction = store.createRecord('recording', { + authorized_actions: [], + type: 'unknown', + }); + + assert.false( + canService.can( + 'downloadAsciiCast recording', + recordingWithAuthorizedAction + ) + ); + assert.false( + canService.can( + 'downloadAsciiCast recording', + recordingWithoutAuthorizedAction + ) + ); + }); +}); diff --git a/ui/admin/tests/unit/abilities/storage-bucket-test.js b/ui/admin/tests/unit/abilities/storage-bucket-test.js index 3961c60dd..58b5c4319 100644 --- a/ui/admin/tests/unit/abilities/storage-bucket-test.js +++ b/ui/admin/tests/unit/abilities/storage-bucket-test.js @@ -14,16 +14,18 @@ module('Unit | Abilities | storage-bucket', function (hooks) { setupTest(hooks); let features; + let canService; + let store; hooks.beforeEach(function () { features = this.owner.lookup('service:features'); features.enable('session-recording'); + canService = this.owner.lookup('service:can'); + store = this.owner.lookup('service:store'); }); test('can read storage bucket when authorized and feature is enabled', function (assert) { assert.expect(1); - const canService = this.owner.lookup('service:can'); - const store = this.owner.lookup('service:store'); const storageBucket = store.createRecord('storage-bucket', { authorized_actions: ['read'], @@ -36,8 +38,6 @@ module('Unit | Abilities | storage-bucket', function (hooks) { test('cannot read storage bucket when unauthorized and feature is enabled', function (assert) { assert.expect(1); - const canService = this.owner.lookup('service:can'); - const store = this.owner.lookup('service:store'); const storageBucket = store.createRecord('storage-bucket', { authorized_actions: [], @@ -50,8 +50,6 @@ module('Unit | Abilities | storage-bucket', function (hooks) { test('cannot read storage bucket when authorized and feature is disabled', function (assert) { assert.expect(1); - const canService = this.owner.lookup('service:can'); - const store = this.owner.lookup('service:store'); features.disable('session-recording'); const storageBucket = store.createRecord('storage-bucket', { @@ -65,8 +63,6 @@ module('Unit | Abilities | storage-bucket', function (hooks) { test('cannot read storage bucket when unauthorized and feature is disabled', function (assert) { assert.expect(1); - const canService = this.owner.lookup('service:can'); - const store = this.owner.lookup('service:store'); features.disable('session-recording'); const storageBucket = store.createRecord('storage-bucket', { @@ -80,8 +76,6 @@ module('Unit | Abilities | storage-bucket', function (hooks) { test('can list storage bucket when authorized and in global scope', function (assert) { assert.expect(1); - const canService = this.owner.lookup('service:can'); - const store = this.owner.lookup('service:store'); const scopeModel = store.createRecord('scope', { authorized_collection_actions: { 'storage-buckets': ['list'] }, @@ -98,8 +92,6 @@ module('Unit | Abilities | storage-bucket', function (hooks) { test('cannot list storage bucket when unauthorized and in global scope', function (assert) { assert.expect(1); - const canService = this.owner.lookup('service:can'); - const store = this.owner.lookup('service:store'); const scopeModel = store.createRecord('scope', { authorized_collection_actions: { 'storage-buckets': [] }, @@ -116,8 +108,6 @@ module('Unit | Abilities | storage-bucket', function (hooks) { test('cannot list storage bucket when authorized and in org scope', function (assert) { assert.expect(1); - const canService = this.owner.lookup('service:can'); - const store = this.owner.lookup('service:store'); const scopeModel = store.createRecord('scope', { authorized_collection_actions: { 'storage-buckets': ['list'] }, @@ -134,8 +124,6 @@ module('Unit | Abilities | storage-bucket', function (hooks) { test('can create storage bucket when authorized and in global scope', function (assert) { assert.expect(1); - const canService = this.owner.lookup('service:can'); - const store = this.owner.lookup('service:store'); const scopeModel = store.createRecord('scope', { authorized_collection_actions: { 'storage-buckets': ['create'] }, @@ -152,8 +140,6 @@ module('Unit | Abilities | storage-bucket', function (hooks) { test('can create storage bucket when authorized and in org scope', function (assert) { assert.expect(1); - const canService = this.owner.lookup('service:can'); - const store = this.owner.lookup('service:store'); const scopeModel = store.createRecord('scope', { authorized_collection_actions: { 'storage-buckets': ['create'] }, @@ -170,8 +156,6 @@ module('Unit | Abilities | storage-bucket', function (hooks) { test('cannot create storage bucket when authorized and in project scope', function (assert) { assert.expect(1); - const canService = this.owner.lookup('service:can'); - const store = this.owner.lookup('service:store'); const scopeModel = store.createRecord('scope', { authorized_collection_actions: { 'storage-buckets': ['create'] }, @@ -188,8 +172,6 @@ module('Unit | Abilities | storage-bucket', function (hooks) { test('cannot create storage bucket when unauthorized', function (assert) { assert.expect(1); - const canService = this.owner.lookup('service:can'); - const store = this.owner.lookup('service:store'); const scopeModel = store.createRecord('scope', { authorized_collection_actions: { 'storage-buckets': [] }, @@ -206,8 +188,23 @@ module('Unit | Abilities | storage-bucket', function (hooks) { test('can navigate to storage bucket when authorized', function (assert) { assert.expect(1); - const canService = this.owner.lookup('service:can'); - const store = this.owner.lookup('service:store'); + + const scopeModel = store.createRecord('scope', { + authorized_collection_actions: { 'storage-buckets': ['create'] }, + type: 'global', + id: 'global', + }); + + assert.true( + canService.can('navigate storage-bucket', scopeModel, { + collection: 'storage-buckets', + }) + ); + }); + + test('cannot navigate to storage bucket when authorized and feature is disabled', function (assert) { + assert.expect(1); + features.disable('session-recording'); const scopeModel = store.createRecord('scope', { authorized_collection_actions: { 'storage-buckets': ['create'] }, From d08ce29e5a3cb93e6c700ae007bd5c68fb2fe3ad Mon Sep 17 00:00:00 2001 From: Zhihe Li Date: Thu, 16 Mar 2023 13:49:04 -0400 Subject: [PATCH 044/193] Chore/update model names (#125) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: πŸ€– Rename recording to session-recording * chore: πŸ€– Update names for connection models * chore: πŸ€– Update channel models to new name * chore: πŸ€– Update remaining models after merge conflict --- .../{recording.js => session-recording.js} | 2 +- .../{channel.js => channel-recording.js} | 2 +- ...{connection.js => connection-recording.js} | 2 +- .../{recording.js => session-recording.js} | 4 +- addons/api/addon/models/channel-recording.js | 27 ++ addons/api/addon/models/channel.js | 25 -- .../api/addon/models/connection-recording.js | 7 + addons/api/addon/models/connection.js | 7 - addons/api/addon/models/recording.js | 25 -- addons/api/addon/models/session-recording.js | 44 +++ ...{connection.js => connection-recording.js} | 2 +- .../{recording.js => session-recording.js} | 2 +- .../{recording.js => session-recording.js} | 0 addons/api/app/models/channel-recording.js | 1 + addons/api/app/models/channel.js | 1 - addons/api/app/models/connection-recording.js | 1 + addons/api/app/models/connection.js | 1 - addons/api/app/models/recording.js | 1 - addons/api/app/models/session-recording.js | 1 + .../app/serializers/connection-recording.js | 1 + addons/api/app/serializers/connection.js | 1 - addons/api/app/serializers/recording.js | 1 - .../api/app/serializers/session-recording.js | 1 + addons/api/mirage/config.js | 8 +- .../{channel.js => channel-recording.js} | 4 +- ...{connection.js => connection-recording.js} | 2 +- addons/api/mirage/factories/scope.js | 2 +- .../{recording.js => session-recording.js} | 22 +- .../{channel.js => channel-recording.js} | 2 +- ...{connection.js => connection-recording.js} | 2 +- .../{recording.js => session-recording.js} | 2 +- .../{channel.js => channel-recording.js} | 2 +- ...{connection.js => connection-recording.js} | 4 +- .../{recording.js => session-recording.js} | 2 +- addons/api/mirage/scenarios/default.js | 6 +- .../{channel.js => channel-recording.js} | 2 +- ...{connection.js => connection-recording.js} | 12 +- .../{recording.js => session-recording.js} | 19 +- ...nnel-test.js => channel-recording-test.js} | 18 +- ...n-test.js => connection-recording-test.js} | 12 +- ...ding-test.js => session-recording-test.js} | 28 +- ...g-test.js => connection-recording-test.js} | 6 +- ...tion-test.js => session-recording-test.js} | 6 +- .../{recording.js => session-recording.js} | 4 +- .../tests/unit/abilities/recording-test.js | 221 -------------- .../unit/abilities/session-recording-test.js | 269 ++++++++++++++++++ 46 files changed, 442 insertions(+), 372 deletions(-) rename addons/api/addon/abilities/{recording.js => session-recording.js} (90%) rename addons/api/addon/generated/models/{channel.js => channel-recording.js} (93%) rename addons/api/addon/generated/models/{connection.js => connection-recording.js} (92%) rename addons/api/addon/generated/models/{recording.js => session-recording.js} (91%) create mode 100644 addons/api/addon/models/channel-recording.js delete mode 100644 addons/api/addon/models/channel.js create mode 100644 addons/api/addon/models/connection-recording.js delete mode 100644 addons/api/addon/models/connection.js delete mode 100644 addons/api/addon/models/recording.js create mode 100644 addons/api/addon/models/session-recording.js rename addons/api/addon/serializers/{connection.js => connection-recording.js} (83%) rename addons/api/addon/serializers/{recording.js => session-recording.js} (82%) rename addons/api/app/abilities/{recording.js => session-recording.js} (100%) create mode 100644 addons/api/app/models/channel-recording.js delete mode 100644 addons/api/app/models/channel.js create mode 100644 addons/api/app/models/connection-recording.js delete mode 100644 addons/api/app/models/connection.js delete mode 100644 addons/api/app/models/recording.js create mode 100644 addons/api/app/models/session-recording.js create mode 100644 addons/api/app/serializers/connection-recording.js delete mode 100644 addons/api/app/serializers/connection.js delete mode 100644 addons/api/app/serializers/recording.js create mode 100644 addons/api/app/serializers/session-recording.js rename addons/api/mirage/factories/{channel.js => channel-recording.js} (61%) rename addons/api/mirage/factories/{connection.js => connection-recording.js} (73%) rename addons/api/mirage/factories/{recording.js => session-recording.js} (68%) rename addons/api/mirage/generated/factories/{channel.js => channel-recording.js} (91%) rename addons/api/mirage/generated/factories/{connection.js => connection-recording.js} (91%) rename addons/api/mirage/generated/factories/{recording.js => session-recording.js} (93%) rename addons/api/mirage/models/{channel.js => channel-recording.js} (81%) rename addons/api/mirage/models/{connection.js => connection-recording.js} (71%) rename addons/api/mirage/models/{recording.js => session-recording.js} (87%) rename addons/api/mirage/serializers/{channel.js => channel-recording.js} (84%) rename addons/api/mirage/serializers/{connection.js => connection-recording.js} (59%) rename addons/api/mirage/serializers/{recording.js => session-recording.js} (65%) rename addons/api/tests/unit/models/{channel-test.js => channel-recording-test.js} (60%) rename addons/api/tests/unit/models/{connection-test.js => connection-recording-test.js} (50%) rename addons/api/tests/unit/models/{recording-test.js => session-recording-test.js} (56%) rename addons/api/tests/unit/serializers/{recording-test.js => connection-recording-test.js} (68%) rename addons/api/tests/unit/serializers/{connection-test.js => session-recording-test.js} (70%) rename ui/admin/app/abilities/{recording.js => session-recording.js} (83%) delete mode 100644 ui/admin/tests/unit/abilities/recording-test.js create mode 100644 ui/admin/tests/unit/abilities/session-recording-test.js diff --git a/addons/api/addon/abilities/recording.js b/addons/api/addon/abilities/session-recording.js similarity index 90% rename from addons/api/addon/abilities/recording.js rename to addons/api/addon/abilities/session-recording.js index 7d9da0957..6cd22ba84 100644 --- a/addons/api/addon/abilities/recording.js +++ b/addons/api/addon/abilities/session-recording.js @@ -8,7 +8,7 @@ import ModelAbility from './model'; /** * Provides abilities for session recordings. */ -export default class RecordingAbility extends ModelAbility { +export default class SessionRecordingAbility extends ModelAbility { // =services // =permissions diff --git a/addons/api/addon/generated/models/channel.js b/addons/api/addon/generated/models/channel-recording.js similarity index 93% rename from addons/api/addon/generated/models/channel.js rename to addons/api/addon/generated/models/channel-recording.js index 6f9a68b71..841930aac 100644 --- a/addons/api/addon/generated/models/channel.js +++ b/addons/api/addon/generated/models/channel-recording.js @@ -9,7 +9,7 @@ import { attr } from '@ember-data/model'; /** * A channel contains data for a single channel within a connection. */ -export default class GeneratedChannelModel extends BaseModel { +export default class GeneratedChannelRecordingModel extends BaseModel { // =attributes @attr('string', { diff --git a/addons/api/addon/generated/models/connection.js b/addons/api/addon/generated/models/connection-recording.js similarity index 92% rename from addons/api/addon/generated/models/connection.js rename to addons/api/addon/generated/models/connection-recording.js index b0d28d7f2..867b20c91 100644 --- a/addons/api/addon/generated/models/connection.js +++ b/addons/api/addon/generated/models/connection-recording.js @@ -9,7 +9,7 @@ import { attr } from '@ember-data/model'; /** * A connection contains data for a boundary connection within a session. */ -export default class GeneratedConnectionModel extends BaseModel { +export default class GeneratedConnectionRecordingModel extends BaseModel { // =attributes @attr('number', { diff --git a/addons/api/addon/generated/models/recording.js b/addons/api/addon/generated/models/session-recording.js similarity index 91% rename from addons/api/addon/generated/models/recording.js rename to addons/api/addon/generated/models/session-recording.js index 4853894e6..234f5acb0 100644 --- a/addons/api/addon/generated/models/recording.js +++ b/addons/api/addon/generated/models/session-recording.js @@ -7,9 +7,9 @@ import BaseModel from '../../models/base'; import { attr } from '@ember-data/model'; /** - * A recording contains all data related to session recordings + * A session recording contains all data related to session recordings */ -export default class GeneratedRecordingModel extends BaseModel { +export default class GeneratedSessionRecordingModel extends BaseModel { // =attributes @attr('string', { diff --git a/addons/api/addon/models/channel-recording.js b/addons/api/addon/models/channel-recording.js new file mode 100644 index 000000000..6652b11fe --- /dev/null +++ b/addons/api/addon/models/channel-recording.js @@ -0,0 +1,27 @@ +import GeneratedChannelRecordingModel from '../generated/models/channel-recording'; +import { belongsTo } from '@ember-data/model'; + +export const TYPE_CHANNEL_RECORDING_SESSION = 'session'; +export const TYPES_CHANNEL_RECORDING = Object.freeze([ + TYPE_CHANNEL_RECORDING_SESSION, +]); + +export default class ChannelRecordingModel extends GeneratedChannelRecordingModel { + @belongsTo('connection-recording') connection_recording; + + /** + * True if the channel type is `session`. + * @type {boolean} + */ + get isSession() { + return this.type === TYPE_CHANNEL_RECORDING_SESSION; + } + + /** + * True if the channel is an unknown type. + * @type {boolean} + */ + get isUnknown() { + return !TYPES_CHANNEL_RECORDING.includes(this.type); + } +} diff --git a/addons/api/addon/models/channel.js b/addons/api/addon/models/channel.js deleted file mode 100644 index f0e776d8e..000000000 --- a/addons/api/addon/models/channel.js +++ /dev/null @@ -1,25 +0,0 @@ -import GeneratedChannelModel from '../generated/models/channel'; -import { belongsTo } from '@ember-data/model'; - -export const TYPE_CHANNEL_SESSION = 'session'; -export const TYPES_CHANNEL = Object.freeze([TYPE_CHANNEL_SESSION]); - -export default class ChannelModel extends GeneratedChannelModel { - @belongsTo('connection') connection; - - /** - * True if the channel type is `session`. - * @type {boolean} - */ - get isSession() { - return this.type === TYPE_CHANNEL_SESSION; - } - - /** - * True if the channel is an unknown type. - * @type {boolean} - */ - get isUnknown() { - return !TYPES_CHANNEL.includes(this.type); - } -} diff --git a/addons/api/addon/models/connection-recording.js b/addons/api/addon/models/connection-recording.js new file mode 100644 index 000000000..58ee85449 --- /dev/null +++ b/addons/api/addon/models/connection-recording.js @@ -0,0 +1,7 @@ +import GeneratedConnectionRecordingModel from '../generated/models/connection-recording'; +import { belongsTo, hasMany } from '@ember-data/model'; + +export default class ConnectionRecordingModel extends GeneratedConnectionRecordingModel { + @belongsTo('session-recording') session_recording; + @hasMany('channel-recording') channel_recordings; +} diff --git a/addons/api/addon/models/connection.js b/addons/api/addon/models/connection.js deleted file mode 100644 index 482e85b4d..000000000 --- a/addons/api/addon/models/connection.js +++ /dev/null @@ -1,7 +0,0 @@ -import GeneratedConnectionModel from '../generated/models/connection'; -import { belongsTo, hasMany } from '@ember-data/model'; - -export default class ConnectionModel extends GeneratedConnectionModel { - @belongsTo('recording') recording; - @hasMany('channel') channels; -} diff --git a/addons/api/addon/models/recording.js b/addons/api/addon/models/recording.js deleted file mode 100644 index bea1ee92d..000000000 --- a/addons/api/addon/models/recording.js +++ /dev/null @@ -1,25 +0,0 @@ -import GeneratedRecordingModel from '../generated/models/recording'; -import { hasMany } from '@ember-data/model'; - -export const TYPE_RECORDING_SSH = 'ssh'; -export const TYPES_RECORDING = Object.freeze([TYPE_RECORDING_SSH]); - -export default class RecordingModel extends GeneratedRecordingModel { - @hasMany('connection') connections; - - /** - * True if the recording type is `ssh`. - * @type {boolean} - */ - get isSSH() { - return this.type === TYPE_RECORDING_SSH; - } - - /** - * True if the recording is an unknown type. - * @type {boolean} - */ - get isUnknown() { - return !TYPES_RECORDING.includes(this.type); - } -} diff --git a/addons/api/addon/models/session-recording.js b/addons/api/addon/models/session-recording.js new file mode 100644 index 000000000..6a125140d --- /dev/null +++ b/addons/api/addon/models/session-recording.js @@ -0,0 +1,44 @@ +import GeneratedSessionRecordingModel from '../generated/models/session-recording'; +import { hasMany } from '@ember-data/model'; +import { inject as service } from '@ember/service'; + +export const TYPE_SESSION_RECORDING_SSH = 'ssh'; +export const TYPES_SESSION_RECORDING = Object.freeze([ + TYPE_SESSION_RECORDING_SSH, +]); + +export default class SessionRecordingModel extends GeneratedSessionRecordingModel { + @hasMany('connection-recording') connection_recordings; + + @service store; + + /** + * True if the session recording type is `ssh`. + * @type {boolean} + */ + get isSSH() { + return this.type === TYPE_SESSION_RECORDING_SSH; + } + + /** + * True if the session recording is an unknown type. + * @type {boolean} + */ + get isUnknown() { + return !TYPES_SESSION_RECORDING.includes(this.type); + } + + getAsciiCast({ connectionId, channelId, mimeType }) { + const adapter = this.store.adapterFor('application'); + const options = { adapterOptions: { method: 'download' } }; + const url = adapter.buildURL( + 'session-recording', + this.id, + options, + 'findRecord' + ); + return adapter.ajax(url, 'GET', { + data: { connectionId, channelId, mimeType }, + }); + } +} diff --git a/addons/api/addon/serializers/connection.js b/addons/api/addon/serializers/connection-recording.js similarity index 83% rename from addons/api/addon/serializers/connection.js rename to addons/api/addon/serializers/connection-recording.js index 95c01903b..4f385ac2b 100644 --- a/addons/api/addon/serializers/connection.js +++ b/addons/api/addon/serializers/connection-recording.js @@ -5,6 +5,6 @@ export default class ConnectionSerializer extends ApplicationSerializer.extend( EmbeddedRecordsMixin ) { attrs = { - channels: { embedded: 'always' }, + channel_recordings: { embedded: 'always' }, }; } diff --git a/addons/api/addon/serializers/recording.js b/addons/api/addon/serializers/session-recording.js similarity index 82% rename from addons/api/addon/serializers/recording.js rename to addons/api/addon/serializers/session-recording.js index 6759db0dd..0512b8667 100644 --- a/addons/api/addon/serializers/recording.js +++ b/addons/api/addon/serializers/session-recording.js @@ -4,6 +4,6 @@ export default class RecordingSerializer extends ApplicationSerializer.extend( EmbeddedRecordsMixin ) { attrs = { - connections: { embedded: 'always' }, + connection_recordings: { embedded: 'always' }, }; } diff --git a/addons/api/app/abilities/recording.js b/addons/api/app/abilities/session-recording.js similarity index 100% rename from addons/api/app/abilities/recording.js rename to addons/api/app/abilities/session-recording.js diff --git a/addons/api/app/models/channel-recording.js b/addons/api/app/models/channel-recording.js new file mode 100644 index 000000000..3567b0777 --- /dev/null +++ b/addons/api/app/models/channel-recording.js @@ -0,0 +1 @@ +export { default } from 'api/models/channel-recording'; diff --git a/addons/api/app/models/channel.js b/addons/api/app/models/channel.js deleted file mode 100644 index 83fa2e823..000000000 --- a/addons/api/app/models/channel.js +++ /dev/null @@ -1 +0,0 @@ -export { default } from 'api/models/channel'; diff --git a/addons/api/app/models/connection-recording.js b/addons/api/app/models/connection-recording.js new file mode 100644 index 000000000..bb13c4dbe --- /dev/null +++ b/addons/api/app/models/connection-recording.js @@ -0,0 +1 @@ +export { default } from 'api/models/connection-recording'; diff --git a/addons/api/app/models/connection.js b/addons/api/app/models/connection.js deleted file mode 100644 index 17c9eb2ac..000000000 --- a/addons/api/app/models/connection.js +++ /dev/null @@ -1 +0,0 @@ -export { default } from 'api/models/connection'; diff --git a/addons/api/app/models/recording.js b/addons/api/app/models/recording.js deleted file mode 100644 index bdcbf74be..000000000 --- a/addons/api/app/models/recording.js +++ /dev/null @@ -1 +0,0 @@ -export { default } from 'api/models/recording'; diff --git a/addons/api/app/models/session-recording.js b/addons/api/app/models/session-recording.js new file mode 100644 index 000000000..2e4b944fa --- /dev/null +++ b/addons/api/app/models/session-recording.js @@ -0,0 +1 @@ +export { default } from 'api/models/session-recording'; diff --git a/addons/api/app/serializers/connection-recording.js b/addons/api/app/serializers/connection-recording.js new file mode 100644 index 000000000..cf62e55de --- /dev/null +++ b/addons/api/app/serializers/connection-recording.js @@ -0,0 +1 @@ +export { default } from 'api/serializers/connection-recording'; diff --git a/addons/api/app/serializers/connection.js b/addons/api/app/serializers/connection.js deleted file mode 100644 index ab831ba04..000000000 --- a/addons/api/app/serializers/connection.js +++ /dev/null @@ -1 +0,0 @@ -export { default } from 'api/serializers/connection'; diff --git a/addons/api/app/serializers/recording.js b/addons/api/app/serializers/recording.js deleted file mode 100644 index 921180bea..000000000 --- a/addons/api/app/serializers/recording.js +++ /dev/null @@ -1 +0,0 @@ -export { default } from 'api/serializers/recording'; diff --git a/addons/api/app/serializers/session-recording.js b/addons/api/app/serializers/session-recording.js new file mode 100644 index 000000000..57403d214 --- /dev/null +++ b/addons/api/app/serializers/session-recording.js @@ -0,0 +1 @@ +export { default } from 'api/serializers/session-recording'; diff --git a/addons/api/mirage/config.js b/addons/api/mirage/config.js index 648229604..29c98b72a 100644 --- a/addons/api/mirage/config.js +++ b/addons/api/mirage/config.js @@ -688,12 +688,12 @@ function routes() { // session recordings this.get( - '/recordings', - ({ recordings }, { queryParams: { scope_id: scopeId } }) => { - return recordings.where({ scopeId }); + '/session-recordings', + ({ sessionRecordings }, { queryParams: { scope_id: scopeId } }) => { + return sessionRecordings.where({ scopeId }); } ); - this.get('/recordings/:id'); + this.get('/session-recordings/:id'); /* Uncomment the following line and the Response import above * Then change the response code to simulate error responses. diff --git a/addons/api/mirage/factories/channel.js b/addons/api/mirage/factories/channel-recording.js similarity index 61% rename from addons/api/mirage/factories/channel.js rename to addons/api/mirage/factories/channel-recording.js index 812d7da44..3880e60d6 100644 --- a/addons/api/mirage/factories/channel.js +++ b/addons/api/mirage/factories/channel-recording.js @@ -3,9 +3,9 @@ * SPDX-License-Identifier: MPL-2.0 */ -import factory from '../generated/factories/channel'; +import factory from '../generated/factories/channel-recording'; import generateId from '../helpers/id'; -import { TYPES_CHANNEL as types } from 'api/models/channel'; +import { TYPES_CHANNEL_RECORDING as types } from 'api/models/channel-recording'; export default factory.extend({ id: () => generateId('srcc_'), diff --git a/addons/api/mirage/factories/connection.js b/addons/api/mirage/factories/connection-recording.js similarity index 73% rename from addons/api/mirage/factories/connection.js rename to addons/api/mirage/factories/connection-recording.js index 455c4941f..13619fa22 100644 --- a/addons/api/mirage/factories/connection.js +++ b/addons/api/mirage/factories/connection-recording.js @@ -3,7 +3,7 @@ * SPDX-License-Identifier: MPL-2.0 */ -import factory from '../generated/factories/connection'; +import factory from '../generated/factories/connection-recording'; import generateId from '../helpers/id'; export default factory.extend({ diff --git a/addons/api/mirage/factories/scope.js b/addons/api/mirage/factories/scope.js index 568efe1df..d94b84186 100644 --- a/addons/api/mirage/factories/scope.js +++ b/addons/api/mirage/factories/scope.js @@ -40,7 +40,7 @@ export default factory.extend({ // Session recording resources are only available on global or org scope if (this.type === 'global' || this.type === 'org') { collectionActions['storage-buckets'] = ['create', 'list']; - collectionActions.recordings = ['list']; + collectionActions['session-recordings'] = ['list']; } return collectionActions; diff --git a/addons/api/mirage/factories/recording.js b/addons/api/mirage/factories/session-recording.js similarity index 68% rename from addons/api/mirage/factories/recording.js rename to addons/api/mirage/factories/session-recording.js index ce2cf9c99..7d7977b4b 100644 --- a/addons/api/mirage/factories/recording.js +++ b/addons/api/mirage/factories/session-recording.js @@ -3,12 +3,12 @@ * SPDX-License-Identifier: MPL-2.0 */ -import factory from '../generated/factories/recording'; +import factory from '../generated/factories/session-recording'; import permissions from '../helpers/permissions'; import generateId from '../helpers/id'; import { faker } from '@faker-js/faker'; import { trait } from 'miragejs'; -import { TYPES_RECORDING as types } from 'api/models/recording'; +import { TYPES_SESSION_RECORDING as types } from 'api/models/session-recording'; const pickRandomElement = (arr) => faker.helpers.arrayElement(arr); export default factory.extend({ @@ -18,14 +18,14 @@ export default factory.extend({ type: (i) => types[i % types.length], authorized_actions: () => - permissions.authorizedActionsFor('recording') || [ + permissions.authorizedActionsFor('session-recording') || [ 'no-op', 'read', 'download', ], withNonExistingUserAndTarget: trait({ - afterCreate(recording, server) { + afterCreate(sessionRecording, server) { const user = pickRandomElement(server.schema.users.all().models); user.id = 'deleted_user'; const session = pickRandomElement(server.schema.sessions.all().models); @@ -33,7 +33,7 @@ export default factory.extend({ const target = session.target; target.id = 'deleted_target'; - recording.update({ + sessionRecording.update({ user, target, session, @@ -42,12 +42,12 @@ export default factory.extend({ }), withExistingUserAndTarget: trait({ - afterCreate(recording, server) { + afterCreate(sessionRecording, server) { const user = pickRandomElement(server.schema.users.all().models); const session = pickRandomElement(server.schema.sessions.all().models); const target = session.target; - recording.update({ + sessionRecording.update({ user, target, session, @@ -56,11 +56,11 @@ export default factory.extend({ }), withConnectionAndChannels: trait({ - afterCreate(recording, server) { + afterCreate(session_recording, server) { server - .createList('connection', 3, { recording }) - .forEach((connection) => { - server.createList('channel', 3, { connection }); + .createList('connection-recording', 3, { session_recording }) + .forEach((connection_recording) => { + server.createList('channel-recording', 3, { connection_recording }); }); }, }), diff --git a/addons/api/mirage/generated/factories/channel.js b/addons/api/mirage/generated/factories/channel-recording.js similarity index 91% rename from addons/api/mirage/generated/factories/channel.js rename to addons/api/mirage/generated/factories/channel-recording.js index e4e37b0f4..8c9602e57 100644 --- a/addons/api/mirage/generated/factories/channel.js +++ b/addons/api/mirage/generated/factories/channel-recording.js @@ -7,7 +7,7 @@ import { Factory } from 'miragejs'; import { faker } from '@faker-js/faker'; /** - * GeneratedChannelModelFactory + * GeneratedChannelRecordingModelFactory */ export default Factory.extend({ bytes_up: () => faker.datatype.number(), diff --git a/addons/api/mirage/generated/factories/connection.js b/addons/api/mirage/generated/factories/connection-recording.js similarity index 91% rename from addons/api/mirage/generated/factories/connection.js rename to addons/api/mirage/generated/factories/connection-recording.js index c58040ded..3f9eb3452 100644 --- a/addons/api/mirage/generated/factories/connection.js +++ b/addons/api/mirage/generated/factories/connection-recording.js @@ -7,7 +7,7 @@ import { Factory } from 'miragejs'; import { faker } from '@faker-js/faker'; /** - * GeneratedConnectionModelFactory + * GeneratedConnectionRecordingModelFactory */ export default Factory.extend({ bytes_up: () => faker.datatype.number(), diff --git a/addons/api/mirage/generated/factories/recording.js b/addons/api/mirage/generated/factories/session-recording.js similarity index 93% rename from addons/api/mirage/generated/factories/recording.js rename to addons/api/mirage/generated/factories/session-recording.js index 51824fd59..731e3dc3b 100644 --- a/addons/api/mirage/generated/factories/recording.js +++ b/addons/api/mirage/generated/factories/session-recording.js @@ -7,7 +7,7 @@ import { Factory } from 'miragejs'; import { faker } from '@faker-js/faker'; /** - * GeneratedRecordModelFactory + * GeneratedSessionRecordingModelFactory */ export default Factory.extend({ bytes_up: () => faker.datatype.number(), diff --git a/addons/api/mirage/models/channel.js b/addons/api/mirage/models/channel-recording.js similarity index 81% rename from addons/api/mirage/models/channel.js rename to addons/api/mirage/models/channel-recording.js index 19ee5e425..857e81844 100644 --- a/addons/api/mirage/models/channel.js +++ b/addons/api/mirage/models/channel-recording.js @@ -6,5 +6,5 @@ import { belongsTo, Model } from 'miragejs'; export default Model.extend({ - connection: belongsTo(), + connection_recording: belongsTo(), }); diff --git a/addons/api/mirage/models/connection.js b/addons/api/mirage/models/connection-recording.js similarity index 71% rename from addons/api/mirage/models/connection.js rename to addons/api/mirage/models/connection-recording.js index 5706ffe4b..eeb2f98de 100644 --- a/addons/api/mirage/models/connection.js +++ b/addons/api/mirage/models/connection-recording.js @@ -6,6 +6,6 @@ import { belongsTo, hasMany, Model } from 'miragejs'; export default Model.extend({ - recording: belongsTo(), - channels: hasMany(), + session_recording: belongsTo(), + channel_recordings: hasMany(), }); diff --git a/addons/api/mirage/models/recording.js b/addons/api/mirage/models/session-recording.js similarity index 87% rename from addons/api/mirage/models/recording.js rename to addons/api/mirage/models/session-recording.js index ec60ca095..c9ad6b47c 100644 --- a/addons/api/mirage/models/recording.js +++ b/addons/api/mirage/models/session-recording.js @@ -10,5 +10,5 @@ export default Model.extend({ user: belongsTo(), session: belongsTo(), target: belongsTo(), - connections: hasMany(), + connection_recordings: hasMany(), }); diff --git a/addons/api/mirage/scenarios/default.js b/addons/api/mirage/scenarios/default.js index e174d7d79..8b90d290c 100644 --- a/addons/api/mirage/scenarios/default.js +++ b/addons/api/mirage/scenarios/default.js @@ -114,20 +114,20 @@ export default function (server) { server.createList('storage-bucket', 3, { scope: globalScope }); server.createList('storage-bucket', 2, { scope: orgScope }); server.createList( - 'recording', + 'session-recording', 3, { scope: globalScope }, 'withConnectionAndChannels', 'withExistingUserAndTarget' ); server.create( - 'recording', + 'session-recording', { scope: globalScope }, 'withConnectionAndChannels', 'withNonExistingUserAndTarget' ); server.createList( - 'recording', + 'session-recording', 2, { scope: orgScope }, 'withConnectionAndChannels', diff --git a/addons/api/mirage/serializers/channel.js b/addons/api/mirage/serializers/channel-recording.js similarity index 84% rename from addons/api/mirage/serializers/channel.js rename to addons/api/mirage/serializers/channel-recording.js index 839e46f34..2fdc38fd8 100644 --- a/addons/api/mirage/serializers/channel.js +++ b/addons/api/mirage/serializers/channel-recording.js @@ -6,5 +6,5 @@ import ApplicationSerializer from './application'; export default ApplicationSerializer.extend({ - modelName: 'channel', + modelName: 'channel-recording', }); diff --git a/addons/api/mirage/serializers/connection.js b/addons/api/mirage/serializers/connection-recording.js similarity index 59% rename from addons/api/mirage/serializers/connection.js rename to addons/api/mirage/serializers/connection-recording.js index 6de18bbec..273b5a45b 100644 --- a/addons/api/mirage/serializers/connection.js +++ b/addons/api/mirage/serializers/connection-recording.js @@ -4,19 +4,19 @@ */ import ApplicationSerializer from './application'; -import ChannelSerializer from './channel'; +import ChannelSerializer from './channel-recording'; export default ApplicationSerializer.extend({ - modelName: 'connection', + modelName: 'connection-recording', _hashForModel(model) { const json = ApplicationSerializer.prototype._hashForModel.apply( this, arguments ); - const { channels } = this.schema; - if (model.channelIds) { - json.channels = model.channelIds.map((id) => { - const channel = channels.find(id); + const { channelRecordings } = this.schema; + if (model.channelRecordingIds) { + json.channel_recordings = model.channelRecordingIds.map((id) => { + const channel = channelRecordings.find(id); return ChannelSerializer.prototype._hashForModel.apply(this, [channel]); }); } diff --git a/addons/api/mirage/serializers/recording.js b/addons/api/mirage/serializers/session-recording.js similarity index 65% rename from addons/api/mirage/serializers/recording.js rename to addons/api/mirage/serializers/session-recording.js index a4ce487d3..59eb43c67 100644 --- a/addons/api/mirage/serializers/recording.js +++ b/addons/api/mirage/serializers/session-recording.js @@ -4,26 +4,27 @@ */ import ApplicationSerializer from './application'; -import ConnectionSerializer from './connection'; +import ConnectionRecordingSerializer from './connection-recording'; import UserSerializer from './user'; import TargetSerializer from './target'; export default ApplicationSerializer.extend({ - modelName: 'recording', + modelName: 'session-recording', _hashForModel(model) { const json = ApplicationSerializer.prototype._hashForModel.apply( this, arguments ); - const { connections, users, targets } = this.schema; + const { connectionRecordings, users, targets } = this.schema; // Manually map our models to the actual embedded json representation - if (model.connectionIds) { - json.connections = model.connectionIds.map((id) => { - const connection = connections.find(id); - return ConnectionSerializer.prototype._hashForModel.apply(this, [ - connection, - ]); + if (model.connectionRecordingIds) { + json.connection_recordings = model.connectionRecordingIds.map((id) => { + const connection = connectionRecordings.find(id); + return ConnectionRecordingSerializer.prototype._hashForModel.apply( + this, + [connection] + ); }); } if (model.userId) { diff --git a/addons/api/tests/unit/models/channel-test.js b/addons/api/tests/unit/models/channel-recording-test.js similarity index 60% rename from addons/api/tests/unit/models/channel-test.js rename to addons/api/tests/unit/models/channel-recording-test.js index 7447e0eb6..0a73c18d0 100644 --- a/addons/api/tests/unit/models/channel-test.js +++ b/addons/api/tests/unit/models/channel-recording-test.js @@ -1,23 +1,23 @@ import { module, test } from 'qunit'; import { setupTest } from 'ember-qunit'; -import { TYPE_CHANNEL_SESSION } from 'api/models/channel'; +import { TYPE_CHANNEL_RECORDING_SESSION } from 'api/models/channel-recording'; -module('Unit | Model | channel', function (hooks) { +module('Unit | Model | channel-recording', function (hooks) { setupTest(hooks); test('it exists', function (assert) { let store = this.owner.lookup('service:store'); - let model = store.createRecord('channel', {}); + let model = store.createRecord('channel-recording', {}); assert.ok(model); }); test('it has isUnknown property and returns the expected values', async function (assert) { assert.expect(2); const store = this.owner.lookup('service:store'); - const modelA = store.createRecord('channel', { - type: TYPE_CHANNEL_SESSION, + const modelA = store.createRecord('channel-recording', { + type: TYPE_CHANNEL_RECORDING_SESSION, }); - const modelB = store.createRecord('channel', { + const modelB = store.createRecord('channel-recording', { type: 'no-such-type', }); assert.false(modelA.isUnknown); @@ -27,10 +27,10 @@ module('Unit | Model | channel', function (hooks) { test('it has isSession property and returns the expected values', async function (assert) { assert.expect(2); const store = this.owner.lookup('service:store'); - const modelA = store.createRecord('channel', { - type: TYPE_CHANNEL_SESSION, + const modelA = store.createRecord('channel-recording', { + type: TYPE_CHANNEL_RECORDING_SESSION, }); - const modelB = store.createRecord('channel', { + const modelB = store.createRecord('channel-recording', { type: 'random', }); assert.true(modelA.isSession); diff --git a/addons/api/tests/unit/models/connection-test.js b/addons/api/tests/unit/models/connection-recording-test.js similarity index 50% rename from addons/api/tests/unit/models/connection-test.js rename to addons/api/tests/unit/models/connection-recording-test.js index e6d50eaa9..30325bf4c 100644 --- a/addons/api/tests/unit/models/connection-test.js +++ b/addons/api/tests/unit/models/connection-recording-test.js @@ -1,23 +1,23 @@ import { module, test } from 'qunit'; import { setupTest } from 'ember-qunit'; -module('Unit | Model | connection', function (hooks) { +module('Unit | Model | connection-recording', function (hooks) { setupTest(hooks); test('it exists', function (assert) { let store = this.owner.lookup('service:store'); - let model = store.createRecord('connection', {}); + let model = store.createRecord('connection-recording', {}); assert.ok(model); }); test('it has channels as a relationship', async function (assert) { assert.expect(1); const store = this.owner.lookup('service:store'); - const model = store.createRecord('connection', { - channels: [store.createRecord('channel')], + const model = store.createRecord('connection-recording', { + channel_recordings: [store.createRecord('channel-recording')], }); - const channels = await model.channels; - assert.strictEqual(channels.length, 1); + const channel_recordings = await model.channel_recordings; + assert.strictEqual(channel_recordings.length, 1); }); }); diff --git a/addons/api/tests/unit/models/recording-test.js b/addons/api/tests/unit/models/session-recording-test.js similarity index 56% rename from addons/api/tests/unit/models/recording-test.js rename to addons/api/tests/unit/models/session-recording-test.js index 096954c8b..ca6705d00 100644 --- a/addons/api/tests/unit/models/recording-test.js +++ b/addons/api/tests/unit/models/session-recording-test.js @@ -1,25 +1,25 @@ import { module, test } from 'qunit'; import { setupTest } from 'ember-qunit'; -import { TYPE_RECORDING_SSH } from 'api/models/recording'; +import { TYPE_SESSION_RECORDING_SSH } from 'api/models/session-recording'; import setupMirage from 'ember-cli-mirage/test-support/setup-mirage'; -module('Unit | Model | recording', function (hooks) { +module('Unit | Model | session-recording', function (hooks) { setupTest(hooks); setupMirage(hooks); test('it exists', function (assert) { let store = this.owner.lookup('service:store'); - let model = store.createRecord('recording', {}); + let model = store.createRecord('session-recording', {}); assert.ok(model); }); test('it has isUnknown property and returns the expected values', async function (assert) { assert.expect(2); const store = this.owner.lookup('service:store'); - const modelA = store.createRecord('recording', { - type: TYPE_RECORDING_SSH, + const modelA = store.createRecord('session-recording', { + type: TYPE_SESSION_RECORDING_SSH, }); - const modelB = store.createRecord('recording', { + const modelB = store.createRecord('session-recording', { type: 'no-such-type', }); assert.false(modelA.isUnknown); @@ -29,10 +29,10 @@ module('Unit | Model | recording', function (hooks) { test('it has isSSH property and returns the expected values', async function (assert) { assert.expect(2); const store = this.owner.lookup('service:store'); - const modelA = store.createRecord('recording', { - type: TYPE_RECORDING_SSH, + const modelA = store.createRecord('session-recording', { + type: TYPE_SESSION_RECORDING_SSH, }); - const modelB = store.createRecord('recording', { + const modelB = store.createRecord('session-recording', { type: 'random', }); assert.true(modelA.isSSH); @@ -42,12 +42,12 @@ module('Unit | Model | recording', function (hooks) { test('it has connections as a relationship', async function (assert) { assert.expect(1); const store = this.owner.lookup('service:store'); - const model = store.createRecord('recording', { - type: TYPE_RECORDING_SSH, - connections: [store.createRecord('connection')], + const model = store.createRecord('session-recording', { + type: TYPE_SESSION_RECORDING_SSH, + connection_recordings: [store.createRecord('connection-recording')], }); - const connections = await model.connections; - assert.strictEqual(connections.length, 1); + const connection_recordings = await model.connection_recordings; + assert.strictEqual(connection_recordings.length, 1); }); }); diff --git a/addons/api/tests/unit/serializers/recording-test.js b/addons/api/tests/unit/serializers/connection-recording-test.js similarity index 68% rename from addons/api/tests/unit/serializers/recording-test.js rename to addons/api/tests/unit/serializers/connection-recording-test.js index 458e02c16..9a72a2f69 100644 --- a/addons/api/tests/unit/serializers/recording-test.js +++ b/addons/api/tests/unit/serializers/connection-recording-test.js @@ -1,20 +1,20 @@ import { module, test } from 'qunit'; import { setupTest } from 'ember-qunit'; -module('Unit | Serializer | recording', function (hooks) { +module('Unit | Serializer | connection-recording-recording', function (hooks) { setupTest(hooks); // Replace this with your real tests. test('it exists', function (assert) { let store = this.owner.lookup('service:store'); - let serializer = store.serializerFor('recording'); + let serializer = store.serializerFor('connection-recording'); assert.ok(serializer); }); test('it serializes records', function (assert) { let store = this.owner.lookup('service:store'); - let record = store.createRecord('recording', {}); + let record = store.createRecord('connection-recording', {}); let serializedRecord = record.serialize(); diff --git a/addons/api/tests/unit/serializers/connection-test.js b/addons/api/tests/unit/serializers/session-recording-test.js similarity index 70% rename from addons/api/tests/unit/serializers/connection-test.js rename to addons/api/tests/unit/serializers/session-recording-test.js index 02a53897d..b1073919a 100644 --- a/addons/api/tests/unit/serializers/connection-test.js +++ b/addons/api/tests/unit/serializers/session-recording-test.js @@ -1,20 +1,20 @@ import { module, test } from 'qunit'; import { setupTest } from 'ember-qunit'; -module('Unit | Serializer | connection', function (hooks) { +module('Unit | Serializer | session-recording', function (hooks) { setupTest(hooks); // Replace this with your real tests. test('it exists', function (assert) { let store = this.owner.lookup('service:store'); - let serializer = store.serializerFor('connection'); + let serializer = store.serializerFor('session-recording'); assert.ok(serializer); }); test('it serializes records', function (assert) { let store = this.owner.lookup('service:store'); - let record = store.createRecord('connection', {}); + let record = store.createRecord('session-recording', {}); let serializedRecord = record.serialize(); diff --git a/ui/admin/app/abilities/recording.js b/ui/admin/app/abilities/session-recording.js similarity index 83% rename from ui/admin/app/abilities/recording.js rename to ui/admin/app/abilities/session-recording.js index 3365397c8..ed0a53499 100644 --- a/ui/admin/app/abilities/recording.js +++ b/ui/admin/app/abilities/session-recording.js @@ -3,10 +3,10 @@ * SPDX-License-Identifier: MPL-2.0 */ -import RecordingAbility from 'api/abilities/recording'; +import SessionRecordingAbility from 'api/abilities/session-recording'; import { inject as service } from '@ember/service'; -export default class OverrideRecordingAbility extends RecordingAbility { +export default class OverrideSessionRecordingAbility extends SessionRecordingAbility { // =service @service features; diff --git a/ui/admin/tests/unit/abilities/recording-test.js b/ui/admin/tests/unit/abilities/recording-test.js deleted file mode 100644 index 05a46b2b5..000000000 --- a/ui/admin/tests/unit/abilities/recording-test.js +++ /dev/null @@ -1,221 +0,0 @@ -/** - * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: MPL-2.0 - */ - -import { module, test } from 'qunit'; -import { setupTest } from 'ember-qunit'; -import { TYPE_RECORDING_SSH } from 'api/models/recording'; - -module('Unit | Abilities | session-recording', function (hooks) { - setupTest(hooks); - - let features; - let canService; - let store; - - hooks.beforeEach(function () { - features = this.owner.lookup('service:features'); - features.enable('session-recording'); - canService = this.owner.lookup('service:can'); - store = this.owner.lookup('service:store'); - }); - - test('can read session recording feature is enabled', function (assert) { - assert.expect(2); - - const recordingWithAuthorizedAction = store.createRecord('recording', { - authorized_actions: ['read'], - type: TYPE_RECORDING_SSH, - }); - const recordingWithoutAuthorizedAction = store.createRecord('recording', { - authorized_actions: [], - type: TYPE_RECORDING_SSH, - }); - - assert.true( - canService.can('read recording', recordingWithAuthorizedAction) - ); - assert.false( - canService.can('read recording', recordingWithoutAuthorizedAction) - ); - }); - - test('cannot read session recording when feature is disabled', function (assert) { - assert.expect(2); - features.disable('session-recording'); - - const recordingWithAuthorizedAction = store.createRecord('recording', { - authorized_actions: ['read'], - type: TYPE_RECORDING_SSH, - }); - const recordingWithoutAuthorizedAction = store.createRecord('recording', { - authorized_actions: [], - type: TYPE_RECORDING_SSH, - }); - - assert.false( - canService.can('read recording', recordingWithAuthorizedAction) - ); - assert.false( - canService.can('read recording', recordingWithoutAuthorizedAction) - ); - }); - - test('can list session recording when in global scope', function (assert) { - assert.expect(2); - - const scopeModelWithAuthorizedAction = store.createRecord('scope', { - authorized_collection_actions: { recordings: ['list'] }, - type: 'global', - id: 'first', - }); - const scopeModelWithoutAuthorizedAction = store.createRecord('scope', { - authorized_collection_actions: { recordings: [] }, - type: 'global', - id: 'second', - }); - - assert.true( - canService.can('list recording', scopeModelWithAuthorizedAction, { - collection: 'recordings', - }) - ); - assert.false( - canService.can('list recording', scopeModelWithoutAuthorizedAction, { - collection: 'recordings', - }) - ); - }); - - test('cannot list session recording when in org scope', function (assert) { - assert.expect(2); - - const scopeModelWithAuthorizedAction = store.createRecord('scope', { - authorized_collection_actions: { recordings: ['list'] }, - type: 'org', - id: 'first', - }); - const scopeModelWithoutAuthorizedAction = store.createRecord('scope', { - authorized_collection_actions: { recordings: [] }, - type: 'org', - id: 'second', - }); - - assert.false( - canService.can('list recording', scopeModelWithAuthorizedAction, { - collection: 'recordings', - }) - ); - assert.false( - canService.can('list recording', scopeModelWithoutAuthorizedAction, { - collection: 'recordings', - }) - ); - }); - - test('can navigate to session recording when feature is enabled', function (assert) { - assert.expect(2); - - const scopeModelWithAuthorizedAction = store.createRecord('scope', { - authorized_collection_actions: { recordings: ['list'] }, - type: 'global', - id: 'first', - }); - const scopeModelWithoutAuthorizedAction = store.createRecord('scope', { - authorized_collection_actions: { recordings: [] }, - type: 'global', - id: 'second', - }); - - assert.true( - canService.can('navigate recording', scopeModelWithAuthorizedAction, { - collection: 'recordings', - }) - ); - assert.false( - canService.can('navigate recording', scopeModelWithoutAuthorizedAction, { - collection: 'recordings', - }) - ); - }); - - test('cannot navigate to session recording when feature is disabled', function (assert) { - assert.expect(2); - features.disable('session-recording'); - - const scopeModelWithAuthorizedAction = store.createRecord('scope', { - authorized_collection_actions: { recordings: ['list'] }, - type: 'global', - id: 'first', - }); - const scopeModelWithoutAuthorizedAction = store.createRecord('scope', { - authorized_collection_actions: { recordings: [] }, - type: 'global', - id: 'second', - }); - - assert.false( - canService.can('navigate recording', scopeModelWithAuthorizedAction, { - collection: 'recordings', - }) - ); - assert.false( - canService.can('navigate recording', scopeModelWithoutAuthorizedAction, { - collection: 'recordings', - }) - ); - }); - - test('can download asciicast when an ssh recording has download authorization', function (assert) { - assert.expect(2); - - const recordingWithAuthorizedAction = store.createRecord('recording', { - authorized_actions: ['download'], - type: TYPE_RECORDING_SSH, - }); - const recordingWithoutAuthorizedAction = store.createRecord('recording', { - authorized_actions: [], - type: TYPE_RECORDING_SSH, - }); - - assert.true( - canService.can( - 'downloadAsciiCast recording', - recordingWithAuthorizedAction - ) - ); - assert.false( - canService.can( - 'downloadAsciiCast recording', - recordingWithoutAuthorizedAction - ) - ); - }); - - test('cannot download asciicast when a recording is not ssh type', function (assert) { - assert.expect(2); - - const recordingWithAuthorizedAction = store.createRecord('recording', { - authorized_actions: ['download'], - type: 'unknown', - }); - const recordingWithoutAuthorizedAction = store.createRecord('recording', { - authorized_actions: [], - type: 'unknown', - }); - - assert.false( - canService.can( - 'downloadAsciiCast recording', - recordingWithAuthorizedAction - ) - ); - assert.false( - canService.can( - 'downloadAsciiCast recording', - recordingWithoutAuthorizedAction - ) - ); - }); -}); diff --git a/ui/admin/tests/unit/abilities/session-recording-test.js b/ui/admin/tests/unit/abilities/session-recording-test.js new file mode 100644 index 000000000..027d716bc --- /dev/null +++ b/ui/admin/tests/unit/abilities/session-recording-test.js @@ -0,0 +1,269 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; +import { TYPE_SESSION_RECORDING_SSH } from 'api/models/session-recording'; + +module('Unit | Abilities | session-recording', function (hooks) { + setupTest(hooks); + + let features; + let canService; + let store; + + hooks.beforeEach(function () { + features = this.owner.lookup('service:features'); + features.enable('session-recording'); + canService = this.owner.lookup('service:can'); + store = this.owner.lookup('service:store'); + }); + + test('can read session recording feature is enabled', function (assert) { + assert.expect(2); + + const recordingWithAuthorizedAction = store.createRecord( + 'session-recording', + { + authorized_actions: ['read'], + type: TYPE_SESSION_RECORDING_SSH, + } + ); + const recordingWithoutAuthorizedAction = store.createRecord( + 'session-recording', + { + authorized_actions: [], + type: TYPE_SESSION_RECORDING_SSH, + } + ); + + assert.true( + canService.can('read session-recording', recordingWithAuthorizedAction) + ); + assert.false( + canService.can('read session-recording', recordingWithoutAuthorizedAction) + ); + }); + + test('cannot read session recording when feature is disabled', function (assert) { + assert.expect(2); + features.disable('session-recording'); + + const recordingWithAuthorizedAction = store.createRecord( + 'session-recording', + { + authorized_actions: ['read'], + type: TYPE_SESSION_RECORDING_SSH, + } + ); + const recordingWithoutAuthorizedAction = store.createRecord( + 'session-recording', + { + authorized_actions: [], + type: TYPE_SESSION_RECORDING_SSH, + } + ); + + assert.false( + canService.can('read session-recording', recordingWithAuthorizedAction) + ); + assert.false( + canService.can('read session-recording', recordingWithoutAuthorizedAction) + ); + }); + + test('can list session recording when in global scope', function (assert) { + assert.expect(2); + + const scopeModelWithAuthorizedAction = store.createRecord('scope', { + authorized_collection_actions: { ['session-recordings']: ['list'] }, + type: 'global', + id: 'first', + }); + const scopeModelWithoutAuthorizedAction = store.createRecord('scope', { + authorized_collection_actions: { ['session-recordings']: [] }, + type: 'global', + id: 'second', + }); + + assert.true( + canService.can('list session-recording', scopeModelWithAuthorizedAction, { + collection: 'session-recordings', + }) + ); + assert.false( + canService.can( + 'list session-recording', + scopeModelWithoutAuthorizedAction, + { + collection: 'session-recordings', + } + ) + ); + }); + + test('cannot list session recording when in org scope', function (assert) { + assert.expect(2); + + const scopeModelWithAuthorizedAction = store.createRecord('scope', { + authorized_collection_actions: { ['session-recordings']: ['list'] }, + type: 'org', + id: 'first', + }); + const scopeModelWithoutAuthorizedAction = store.createRecord('scope', { + authorized_collection_actions: { ['session-recordings']: [] }, + type: 'org', + id: 'second', + }); + + assert.false( + canService.can('list session-recording', scopeModelWithAuthorizedAction, { + collection: 'session-recordings', + }) + ); + assert.false( + canService.can( + 'list session-recording', + scopeModelWithoutAuthorizedAction, + { + collection: 'session-recordings', + } + ) + ); + }); + + test('can navigate to session recording when feature is enabled', function (assert) { + assert.expect(2); + + const scopeModelWithAuthorizedAction = store.createRecord('scope', { + authorized_collection_actions: { ['session-recordings']: ['list'] }, + type: 'global', + id: 'first', + }); + const scopeModelWithoutAuthorizedAction = store.createRecord('scope', { + authorized_collection_actions: { ['session-recordings']: [] }, + type: 'global', + id: 'second', + }); + + assert.true( + canService.can( + 'navigate session-recording', + scopeModelWithAuthorizedAction, + { + collection: 'session-recordings', + } + ) + ); + assert.false( + canService.can( + 'navigate session-recording', + scopeModelWithoutAuthorizedAction, + { + collection: 'session-recordings', + } + ) + ); + }); + + test('cannot navigate to session recording when feature is disabled', function (assert) { + assert.expect(2); + features.disable('session-recording'); + + const scopeModelWithAuthorizedAction = store.createRecord('scope', { + authorized_collection_actions: { ['session-recordings']: ['list'] }, + type: 'global', + id: 'first', + }); + const scopeModelWithoutAuthorizedAction = store.createRecord('scope', { + authorized_collection_actions: { ['session-recordings']: [] }, + type: 'global', + id: 'second', + }); + + assert.false( + canService.can( + 'navigate session-recording', + scopeModelWithAuthorizedAction, + { + collection: 'session-recordings', + } + ) + ); + assert.false( + canService.can( + 'navigate session-recording', + scopeModelWithoutAuthorizedAction, + { + collection: 'session-recordings', + } + ) + ); + }); + + test('can download asciicast when an ssh recording has download authorization', function (assert) { + assert.expect(2); + + const recordingWithAuthorizedAction = store.createRecord( + 'session-recording', + { + authorized_actions: ['download'], + type: TYPE_SESSION_RECORDING_SSH, + } + ); + const recordingWithoutAuthorizedAction = store.createRecord( + 'session-recording', + { + authorized_actions: [], + type: TYPE_SESSION_RECORDING_SSH, + } + ); + + assert.true( + canService.can( + 'downloadAsciiCast session-recording', + recordingWithAuthorizedAction + ) + ); + assert.false( + canService.can( + 'downloadAsciiCast session-recording', + recordingWithoutAuthorizedAction + ) + ); + }); + + test('cannot download asciicast when a recording is not ssh type', function (assert) { + assert.expect(2); + + const recordingWithAuthorizedAction = store.createRecord( + 'session-recording', + { + authorized_actions: ['download'], + type: 'unknown', + } + ); + const recordingWithoutAuthorizedAction = store.createRecord( + 'session-recording', + { + authorized_actions: [], + type: 'unknown', + } + ); + + assert.false( + canService.can( + 'downloadAsciiCast session-recording', + recordingWithAuthorizedAction + ) + ); + assert.false( + canService.can( + 'downloadAsciiCast session-recording', + recordingWithoutAuthorizedAction + ) + ); + }); +}); From c6bcfd32d5ff24d43875dc4d70b2fa83d3b8a2ca Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Date: Thu, 16 Mar 2023 11:46:11 -0700 Subject: [PATCH 045/193] =?UTF-8?q?refactor:=20=F0=9F=92=A1=20Stop=20using?= =?UTF-8?q?=20recording=20store=20to=20use=20session-recording?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../routes/scopes/scope/session-recordings.js | 2 +- .../session-recordings/session-recording.js | 2 +- .../scopes/scope/session-recordings/index.hbs | 21 +++++++++---------- .../session-recording/index.hbs | 4 ++-- 4 files changed, 14 insertions(+), 15 deletions(-) diff --git a/ui/admin/app/routes/scopes/scope/session-recordings.js b/ui/admin/app/routes/scopes/scope/session-recordings.js index d7dc6b09c..1f45a3e95 100644 --- a/ui/admin/app/routes/scopes/scope/session-recordings.js +++ b/ui/admin/app/routes/scopes/scope/session-recordings.js @@ -27,7 +27,7 @@ export default class ScopesScopeSessionRecordingsRoute extends Route { const scope = this.modelFor('scopes.scope'); const { id: scope_id } = scope; // if (this.can.can('list session-recording', scope, { collection: 'session-recordings' })) { - return this.store.query('recording', { scope_id }); + return this.store.query('session-recording', { scope_id }); // } } diff --git a/ui/admin/app/routes/scopes/scope/session-recordings/session-recording.js b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording.js index e09ebbfc8..47ae85ee4 100644 --- a/ui/admin/app/routes/scopes/scope/session-recordings/session-recording.js +++ b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording.js @@ -17,6 +17,6 @@ export default class ScopesScopeSessionRecordingsSessionRecordingRoute extends R } async model({ session_recording_id }) { - return this.store.findRecord('recording', session_recording_id); + return this.store.findRecord('session-recording', session_recording_id); } } diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs index c0a36d055..5762bc212 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs @@ -4,16 +4,15 @@ - - {{@model.session_recording_id}} - -

-

{{format-time-duration 3000}}

-

{{format-time-duration 2700000}}

-

{{format-time-duration 5000000}}

-

{{format-time-duration 177800000}}

+ {{#each @model as |recording|}} +

+ + {{recording.id}} + +

+ {{/each}}
\ No newline at end of file diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs index 0100fa33a..9641c3084 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs @@ -11,10 +11,10 @@ {{@model.id}}

- {{#each @model.connections as |connection|}} + {{#each @model.connection_recordings as |connection|}}

{{t 'resources.session-recording.connection.title'}} {{connection.id}}

- {{#each connection.channels as |channel|}} + {{#each connection.channel_recordings as |channel|}}

Date: Thu, 16 Mar 2023 15:25:16 -0400 Subject: [PATCH 046/193] Icu 8190 ember data recording asciicast (#124) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 🎸 Add asciicast getter and adapter βœ… Closes: ICU-8190 --- addons/api/addon/models/session-recording.js | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/addons/api/addon/models/session-recording.js b/addons/api/addon/models/session-recording.js index 6a125140d..c1d8a4d83 100644 --- a/addons/api/addon/models/session-recording.js +++ b/addons/api/addon/models/session-recording.js @@ -28,17 +28,25 @@ export default class SessionRecordingModel extends GeneratedSessionRecordingMode return !TYPES_SESSION_RECORDING.includes(this.type); } - getAsciiCast({ connectionId, channelId, mimeType }) { + /** + * Download the recording for either session, connection, or channels. + * id can be the session ID, session recording ID, connection recording ID, + * or the channel recording ID. + * @param {string} id + * @param {string} mimeType + * @returns {Promise} + */ + getAsciiCast(id) { const adapter = this.store.adapterFor('application'); const options = { adapterOptions: { method: 'download' } }; const url = adapter.buildURL( 'session-recording', - this.id, + id, options, 'findRecord' ); return adapter.ajax(url, 'GET', { - data: { connectionId, channelId, mimeType }, + data: { mimeType: 'application/x-asciicast' }, }); } } From 2c978097309562deb815b6bf78e5e38a7e062fe6 Mon Sep 17 00:00:00 2001 From: lisbet-alvarez <107949262+lisbet-alvarez@users.noreply.github.com> Date: Fri, 17 Mar 2023 08:05:59 -0700 Subject: [PATCH 047/193] =?UTF-8?q?test:=20=F0=9F=92=8D=20add=20related=20?= =?UTF-8?q?acceptance=20tests=20(#122)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * test: πŸ’ modify acceptance tests for listing a bucket βœ… Closes: ICU-8230 --- .../acceptance/storage-buckets/list-test.js | 78 +++++++++++++++++-- .../acceptance/storage-buckets/read-test.js | 1 + 2 files changed, 71 insertions(+), 8 deletions(-) diff --git a/ui/admin/tests/acceptance/storage-buckets/list-test.js b/ui/admin/tests/acceptance/storage-buckets/list-test.js index 3821a4631..c81abb0b2 100644 --- a/ui/admin/tests/acceptance/storage-buckets/list-test.js +++ b/ui/admin/tests/acceptance/storage-buckets/list-test.js @@ -4,7 +4,7 @@ */ import { module, test } from 'qunit'; -import { visit } from '@ember/test-helpers'; +import { visit, click, currentURL } from '@ember/test-helpers'; import { setupApplicationTest } from 'admin/tests/helpers'; import setupMirage from 'ember-cli-mirage/test-support/setup-mirage'; import { authenticateSession } from 'ember-simple-auth/test-support'; @@ -14,18 +14,26 @@ module('Acceptance | storage-buckets | list', function (hooks) { setupMirage(hooks); let features; - const STORAGE_BUCKET_LINK = 'Storage Buckets'; + let intl; + + const STORAGE_BUCKET_TITLE = 'Storage Buckets'; + const MESSAGE_DESCRIPTION_SELECTOR = '.rose-message-description'; + const MESSAGE_LINK_SELECTOR = '.rose-message-body .hds-link-standalone'; + const DROPDOWN_BUTTON_SELECTOR = '.hds-dropdown-toggle-icon'; + const DROPDOWN_ITEM_SELECTOR = '.hds-dropdown-list-item a'; const instances = { scopes: { global: null, org: null, }, + storageBucket: null, }; const urls = { globalScope: null, storageBuckets: null, + storageBucket: null, }; hooks.beforeEach(function () { @@ -37,13 +45,14 @@ module('Acceptance | storage-buckets | list', function (hooks) { urls.globalScope = `/scopes/global`; urls.storageBuckets = `${urls.globalScope}/storage-buckets`; + intl = this.owner.lookup('service:intl'); features = this.owner.lookup('service:features'); features.enable('session-recording'); authenticateSession({}); }); test('users can navigate to storage-buckets with proper authorization', async function (assert) { - assert.expect(3); + assert.expect(5); await visit(urls.globalScope); @@ -58,10 +67,18 @@ module('Acceptance | storage-buckets | list', function (hooks) { ].includes('create') ); assert.dom(`[href="${urls.storageBuckets}"]`).exists(); + + // Tests that correct message is displayed when no buckets exist + await click(`[href="${urls.storageBuckets}"]`); + + assert + .dom(MESSAGE_DESCRIPTION_SELECTOR) + .hasText(intl.t('resources.storage-bucket.messages.none.description')); + assert.dom(MESSAGE_LINK_SELECTOR).exists(); }); test('user cannot navigate to index without either list or create actions', async function (assert) { - assert.expect(3); + assert.expect(5); instances.scopes.global.authorized_collection_actions['storage-buckets'] = []; @@ -79,11 +96,21 @@ module('Acceptance | storage-buckets | list', function (hooks) { ); assert .dom('[title="General"] a:nth-of-type(3)') - .doesNotIncludeText(STORAGE_BUCKET_LINK); + .doesNotIncludeText(STORAGE_BUCKET_TITLE); + + // Tests that correct message is displayed when no buckets exist + await visit(urls.storageBuckets); + + assert.dom(MESSAGE_DESCRIPTION_SELECTOR).hasText( + intl.t('descriptions.neither-list-nor-create', { + resource: STORAGE_BUCKET_TITLE, + }) + ); + assert.dom(MESSAGE_LINK_SELECTOR).doesNotExist(); }); test('user can navigate to index with only create action', async function (assert) { - assert.expect(3); + assert.expect(5); instances.scopes.global.authorized_collection_actions['storage-buckets'] = instances.scopes.global.authorized_collection_actions[ 'storage-buckets' @@ -102,10 +129,20 @@ module('Acceptance | storage-buckets | list', function (hooks) { ].includes('create') ); assert.dom(`[href="${urls.storageBuckets}"]`).exists(); + + // Tests that correct message is displayed when no buckets exist + await click(`[href="${urls.storageBuckets}"]`); + + assert.dom(MESSAGE_DESCRIPTION_SELECTOR).hasText( + intl.t('descriptions.create-but-not-list', { + resource: STORAGE_BUCKET_TITLE, + }) + ); + assert.dom(MESSAGE_LINK_SELECTOR).exists(); }); test('user can navigate to index with only list action', async function (assert) { - assert.expect(3); + assert.expect(5); instances.scopes.global.authorized_collection_actions['storage-buckets'] = instances.scopes.global.authorized_collection_actions[ 'storage-buckets' @@ -124,6 +161,14 @@ module('Acceptance | storage-buckets | list', function (hooks) { ].includes('create') ); assert.dom(`[href="${urls.storageBuckets}"]`).exists(); + + // Tests that correct message is displayed when no buckets exist + await click(`[href="${urls.storageBuckets}"]`); + + assert + .dom(MESSAGE_DESCRIPTION_SELECTOR) + .hasText(intl.t('resources.storage-bucket.messages.none.description')); + assert.dom(MESSAGE_LINK_SELECTOR).doesNotExist(); }); test('user cannot navigate to index when feature is disabled', async function (assert) { @@ -134,6 +179,23 @@ module('Acceptance | storage-buckets | list', function (hooks) { assert .dom('[title="General"] a:nth-of-type(2)') - .doesNotIncludeText(STORAGE_BUCKET_LINK); + .doesNotIncludeText(STORAGE_BUCKET_TITLE); + }); + + test('edit action in table directs user to appropriate page', async function (assert) { + assert.expect(3); + await visit(urls.globalScope); + instances.storageBucket = this.server.create('storage-bucket', { + scope: instances.scopes.global, + }); + urls.storageBucket = `${urls.storageBuckets}/${instances.storageBucket.id}`; + + await click(`[href="${urls.storageBuckets}"]`); + await click(DROPDOWN_BUTTON_SELECTOR); + + assert.dom(DROPDOWN_ITEM_SELECTOR).exists(); + assert.dom(DROPDOWN_ITEM_SELECTOR).hasText('Edit'); + await click(DROPDOWN_ITEM_SELECTOR); + assert.strictEqual(currentURL(), urls.storageBucket); }); }); diff --git a/ui/admin/tests/acceptance/storage-buckets/read-test.js b/ui/admin/tests/acceptance/storage-buckets/read-test.js index e734e79f7..f3f47c48c 100644 --- a/ui/admin/tests/acceptance/storage-buckets/read-test.js +++ b/ui/admin/tests/acceptance/storage-buckets/read-test.js @@ -21,6 +21,7 @@ module('Acceptance | storage-buckets | read', function (hooks) { global: null, org: null, }, + storageBucket: null, }; const urls = { From c81e3357d7d082260a145ef4f3c9e1c1022c5b9a Mon Sep 17 00:00:00 2001 From: lisbet-alvarez <107949262+lisbet-alvarez@users.noreply.github.com> Date: Fri, 17 Mar 2023 08:31:51 -0700 Subject: [PATCH 048/193] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20create=20form=20?= =?UTF-8?q?component=20for=20storage=20bucket=20(#118)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 🎸 create form component for storage bucket βœ… Closes: ICU-8235 --- addons/core/translations/resources/en-us.yaml | 26 +- .../components/form/storage-bucket/index.hbs | 249 ++++++++++++++++++ .../components/form/storage-bucket/index.js | 20 ++ .../scopes/scope/storage-buckets/new.js | 21 ++ .../routes/scopes/scope/storage-buckets.js | 38 ++- .../scopes/scope/storage-buckets/new.js | 35 ++- .../scopes/scope/storage-buckets/index.hbs | 4 +- .../scopes/scope/storage-buckets/new.hbs | 26 +- .../scopes/scope/storage-buckets/new-test.js | 16 ++ 9 files changed, 427 insertions(+), 8 deletions(-) create mode 100644 ui/admin/app/components/form/storage-bucket/index.hbs create mode 100644 ui/admin/app/components/form/storage-bucket/index.js create mode 100644 ui/admin/app/controllers/scopes/scope/storage-buckets/new.js create mode 100644 ui/admin/tests/unit/controllers/scopes/scope/storage-buckets/new-test.js diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml index 3e6ee2b6b..9f2fb54f8 100644 --- a/addons/core/translations/resources/en-us.yaml +++ b/addons/core/translations/resources/en-us.yaml @@ -238,8 +238,30 @@ storage-bucket: actions: delete: Delete Storage Bucket form: - scope: Scope - provider: Provider + scope: + label: Scope + help: You will be able to associate this storage bucket with any target. + provider: + label: Provider + help: Boundary currently only supports Amazon S3 storage. + bucket_name: + label: Bucket name + help: The name of this bucket in AWS + bucket_prefix: + label: Bucket prefix + help: The base path where session recordings will be stored. + region: + label: Region + help: The AWS region to use + access_key_id: + label: Access key ID + help: The AWS access key ID to use. + secret_access_key: + label: Secret access key + help: The secret access key to use. + worker_filter: + label: Worker filter + help: Filter for Boundary workers that have network access to your storage. Boolean expression. project: title: Project title_plural: Projects diff --git a/ui/admin/app/components/form/storage-bucket/index.hbs b/ui/admin/app/components/form/storage-bucket/index.hbs new file mode 100644 index 000000000..2413fd29f --- /dev/null +++ b/ui/admin/app/components/form/storage-bucket/index.hbs @@ -0,0 +1,249 @@ +{{! + Copyright (c) HashiCorp, Inc. + SPDX-License-Identifier: MPL-2.0 +}} + + + + {{t 'form.name.label'}} + {{t 'form.name.help'}} + {{#if @model.errors.name}} + + {{#each @model.errors.name as |error|}} + {{error.message}} + {{/each}} + + {{/if}} + + + + {{t 'form.description.label'}} + {{t 'form.description.help'}} + {{#if @model.errors.description}} + + {{#each @model.errors.description as |error|}} + {{error.message}} + {{/each}} + + {{/if}} + + + {{#if (or @model.isNew form.isEditable)}} + + {{t 'resources.storage-bucket.form.scope.label'}} + {{t + 'resources.storage-bucket.form.scope.help' + }} + + {{#each @scopes as |scope|}} + + {{/each}} + + + {{else if @model.scope}} + + {{t 'resources.storage-bucket.form.scope.label'}} + {{t + 'resources.storage-bucket.form.scope.help' + }} + + {{/if}} + + + {{t 'titles.provider'}} + {{t + 'resources.storage-bucket.form.provider.help' + }} + + + + {{t 'resources.storage-bucket.form.bucket_name.label'}} + {{t + 'resources.storage-bucket.form.bucket_name.help' + }} + {{#if @model.errors.bucket_name}} + + {{#each @model.errors.bucket_name as |error|}} + {{error.message}} + {{/each}} + + {{/if}} + + + + {{t 'resources.storage-bucket.form.bucket_prefix.label'}} + {{t + 'resources.storage-bucket.form.bucket_prefix.help' + }} + {{#if @model.errors.bucket_prefix}} + + {{#each @model.errors.bucket_prefix as |error|}} + {{error.message}} + {{/each}} + + {{/if}} + + + + {{t 'resources.storage-bucket.form.region.label'}} + {{t + 'resources.storage-bucket.form.region.help' + }} + {{#if @model.errors.region}} + + {{#each @model.errors.region as |error|}} + {{error.message}} + {{/each}} + + {{/if}} + + + + {{t 'resources.storage-bucket.form.access_key_id.label'}} + {{t + 'resources.storage-bucket.form.access_key_id.help' + }} + {{#if @model.errors.access_key_id}} + + {{#each @model.errors.access_key_id as |error|}} + {{error.message}} + {{/each}} + + {{/if}} + + + + {{t + 'resources.storage-bucket.form.secret_access_key.label' + }} + {{t + 'resources.storage-bucket.form.secret_access_key.help' + }} + {{#if @model.errors.secret_access_key}} + + {{#each @model.errors.secret_access_key as |error|}} + {{error.message}} + {{/each}} + + {{/if}} + + + + {{t 'resources.storage-bucket.form.worker_filter.label'}} + + {{t 'resources.storage-bucket.form.worker_filter.help'}} + {{! TODO: Link to the correct url for worker-filters }} + {{t + 'actions.learn-more' + }} + + {{#if @model.errors.worker_filter}} + + {{#each @model.errors.worker_filter as |error|}} + {{error.message}} + {{/each}} + + {{/if}} + + + {{#if (can 'save model' @model)}} + + {{/if}} + \ No newline at end of file diff --git a/ui/admin/app/components/form/storage-bucket/index.js b/ui/admin/app/components/form/storage-bucket/index.js new file mode 100644 index 000000000..108ee5fb9 --- /dev/null +++ b/ui/admin/app/components/form/storage-bucket/index.js @@ -0,0 +1,20 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import Component from '@glimmer/component'; +import { action } from '@ember/object'; + +export default class FormStorageBucketComponent extends Component { + // =actions + + @action + updateScope(event) { + const selectedScopeId = event.target.value; + const selectedScopeModel = this.args.scopes.find( + (element) => element.model.id === selectedScopeId + ).model; + this.args.model.scopeModel = selectedScopeModel; + } +} diff --git a/ui/admin/app/controllers/scopes/scope/storage-buckets/new.js b/ui/admin/app/controllers/scopes/scope/storage-buckets/new.js new file mode 100644 index 000000000..40f8fcfdc --- /dev/null +++ b/ui/admin/app/controllers/scopes/scope/storage-buckets/new.js @@ -0,0 +1,21 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import Controller from '@ember/controller'; +import { inject as service } from '@ember/service'; + +export default class ScopesScopeStorageBucketsNewController extends Controller { + // =services + + @service intl; + + /** + * Breadcrumb for new route + * @type {string} + */ + get breadCrumb() { + return this.intl.t('resources.storage-bucket.titles.new'); + } +} diff --git a/ui/admin/app/routes/scopes/scope/storage-buckets.js b/ui/admin/app/routes/scopes/scope/storage-buckets.js index 56b2632b6..ca713dd12 100644 --- a/ui/admin/app/routes/scopes/scope/storage-buckets.js +++ b/ui/admin/app/routes/scopes/scope/storage-buckets.js @@ -5,12 +5,14 @@ import Route from '@ember/routing/route'; import { inject as service } from '@ember/service'; +import { action } from '@ember/object'; +import { loading } from 'ember-loading'; +import { notifySuccess, notifyError } from 'core/decorators/notify'; export default class ScopesScopeStorageBucketsRoute extends Route { // =services @service store; - @service intl; @service session; @service can; @service router; @@ -31,10 +33,42 @@ export default class ScopesScopeStorageBucketsRoute extends Route { async model() { const scope = this.modelFor('scopes.scope'); const { id: scope_id } = scope; - if (this.can.can('list storage-bucket', scope, { collection: 'storage-buckets' })) { + if ( + this.can.can('list storage-bucket', scope, { + collection: 'storage-buckets', + }) + ) { return this.store.query('storage-bucket', { scope_id }); } } // =actions + + /** + * Handle save + * @param {StorageBucketModel} storageBucket + */ + @action + @loading + @notifyError(({ message }) => message) + @notifySuccess('notifications.save-success') + async save(storageBucket) { + await storageBucket.save(); + await this.router.transitionTo( + 'scopes.scope.storage-buckets.storage-bucket', + storageBucket + ); + this.refresh(); + } + + /** + * Rollback changes on storage buckets. + * @param {StorageBucketModel} storageBucket + */ + @action + cancel(storageBucket) { + const { isNew } = storageBucket; + storageBucket.rollbackAttributes(); + if (isNew) this.router.transitionTo('scopes.scope.storage-buckets'); + } } diff --git a/ui/admin/app/routes/scopes/scope/storage-buckets/new.js b/ui/admin/app/routes/scopes/scope/storage-buckets/new.js index d318e1a66..130dfe198 100644 --- a/ui/admin/app/routes/scopes/scope/storage-buckets/new.js +++ b/ui/admin/app/routes/scopes/scope/storage-buckets/new.js @@ -5,6 +5,10 @@ import Route from '@ember/routing/route'; import { inject as service } from '@ember/service'; +import { + TYPE_STORAGE_BUCKET_PLUGIN, + TYPE_STORAGE_BUCKET_PLUGIN_AWS_S3, +} from 'api/models/storage-bucket'; export default class ScopesScopeStorageBucketsNewRoute extends Route { // =services @@ -19,8 +23,37 @@ export default class ScopesScopeStorageBucketsNewRoute extends Route { */ model() { const scopeModel = this.modelFor('scopes.scope'); - const record = this.store.createRecord('storage-bucket'); + const record = this.store.createRecord('storage-bucket', { + type: TYPE_STORAGE_BUCKET_PLUGIN, + compositeType: TYPE_STORAGE_BUCKET_PLUGIN_AWS_S3, + }); record.scopeModel = scopeModel; return record; } + + async afterModel() { + let scopes; + const currentScope = this.modelFor('scopes.scope'); + const orgScopes = ( + await this.store.query('scope', { scope_id: 'global' }) + ).map((scope) => ({ model: scope })); + if (currentScope.id === 'global') { + scopes = [{ model: currentScope }, ...orgScopes]; + } else { + scopes = [ + { model: this.store.peekRecord('scope', 'global') }, + ...orgScopes, + ]; + } + this.scopes = scopes; + } + + /** + * Adds available global and org scopes to the context. + * @param {Controller} controller + */ + setupController(controller) { + super.setupController(...arguments); + controller.set('scopes', this.scopes); + } } diff --git a/ui/admin/app/templates/scopes/scope/storage-buckets/index.hbs b/ui/admin/app/templates/scopes/scope/storage-buckets/index.hbs index 01c093f4c..fab3a2a7f 100644 --- a/ui/admin/app/templates/scopes/scope/storage-buckets/index.hbs +++ b/ui/admin/app/templates/scopes/scope/storage-buckets/index.hbs @@ -37,8 +37,8 @@ @columns={{array (hash label=(t 'form.name.label')) (hash label=(t 'form.id.label')) - (hash label=(t 'resources.storage-bucket.form.provider')) - (hash label=(t 'resources.storage-bucket.form.scope')) + (hash label=(t 'resources.storage-bucket.form.provider.label')) + (hash label=(t 'resources.storage-bucket.form.scope.label')) (hash label='') }} > diff --git a/ui/admin/app/templates/scopes/scope/storage-buckets/new.hbs b/ui/admin/app/templates/scopes/scope/storage-buckets/new.hbs index 233691fac..e1b859492 100644 --- a/ui/admin/app/templates/scopes/scope/storage-buckets/new.hbs +++ b/ui/admin/app/templates/scopes/scope/storage-buckets/new.hbs @@ -3,4 +3,28 @@ SPDX-License-Identifier: MPL-2.0 }} -{{page-title (t 'titles.new')}} \ No newline at end of file +{{page-title (t 'titles.new')}} + + + + + + + + {{! TODO: Add valid doc link and description}} +

+ {{t 'resources.storage-bucket.titles.new'}} + +

+ + + + + + + \ No newline at end of file diff --git a/ui/admin/tests/unit/controllers/scopes/scope/storage-buckets/new-test.js b/ui/admin/tests/unit/controllers/scopes/scope/storage-buckets/new-test.js new file mode 100644 index 000000000..3f12de7c5 --- /dev/null +++ b/ui/admin/tests/unit/controllers/scopes/scope/storage-buckets/new-test.js @@ -0,0 +1,16 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'admin/tests/helpers'; + +module( + 'Unit | Controller | scopes/scope/storage-buckets/new', + function (hooks) { + setupTest(hooks); + + test('it exists', function (assert) { + let controller = this.owner.lookup( + 'controller:scopes/scope/storage-buckets/new' + ); + assert.ok(controller); + }); + } +); From a67093efdd3737cbbb228a849b815f8710cfbf2f Mon Sep 17 00:00:00 2001 From: dharini Date: Mon, 20 Mar 2023 22:48:37 +0530 Subject: [PATCH 049/193] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20secret=20input?= =?UTF-8?q?=20field?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- addons/api/mirage/config.js | 1 - addons/core/translations/resources/en-us.yaml | 2 +- .../form/field/secret-input/index.hbs | 36 +++++++++ .../form/field/secret-input/index.js | 59 +++++++++++++++ .../components/form/storage-bucket/index.hbs | 75 +++++++++++++------ ui/admin/app/styles/app.scss | 21 ++++++ 6 files changed, 169 insertions(+), 25 deletions(-) create mode 100644 ui/admin/app/components/form/field/secret-input/index.hbs create mode 100644 ui/admin/app/components/form/field/secret-input/index.js diff --git a/addons/api/mirage/config.js b/addons/api/mirage/config.js index 29c98b72a..3b6781c0a 100644 --- a/addons/api/mirage/config.js +++ b/addons/api/mirage/config.js @@ -677,7 +677,6 @@ function routes() { name: plugin_name, }; } - // Remove the secrets and add the hmac in the response delete attrs.secrets; attrs.secrets_hmac = faker.git.commitSha(); diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml index 9f2fb54f8..89a58b976 100644 --- a/addons/core/translations/resources/en-us.yaml +++ b/addons/core/translations/resources/en-us.yaml @@ -255,7 +255,7 @@ storage-bucket: help: The AWS region to use access_key_id: label: Access key ID - help: The AWS access key ID to use. + help: The Access key ID generated by AWS for the IAM User to use with this host catalog. We will not show this data after it is saved, but you can replace. secret_access_key: label: Secret access key help: The secret access key to use. diff --git a/ui/admin/app/components/form/field/secret-input/index.hbs b/ui/admin/app/components/form/field/secret-input/index.hbs new file mode 100644 index 000000000..1130a2fe4 --- /dev/null +++ b/ui/admin/app/components/form/field/secret-input/index.hbs @@ -0,0 +1,36 @@ +{{! + Copyright (c) HashiCorp, Inc. + SPDX-License-Identifier: MPL-2.0 +}} + +
+ + {{yield F}} + + + {{#if this.isDisabled}} + + {{else if this.isActionable}} + + {{else}} + + {{/if}} +
\ No newline at end of file diff --git a/ui/admin/app/components/form/field/secret-input/index.js b/ui/admin/app/components/form/field/secret-input/index.js new file mode 100644 index 000000000..d07ef164b --- /dev/null +++ b/ui/admin/app/components/form/field/secret-input/index.js @@ -0,0 +1,59 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import Component from '@glimmer/component'; +import { tracked } from '@glimmer/tracking'; +import { action } from '@ember/object'; + +export default class FormFieldSecretInputIndexComponent extends Component { + // =properties + /** + * Tracks when secret can be updated + * @type {boolean} + */ + @tracked editing = false; + @tracked secret; + // =actions + + /** + * Returns true if the resource form is in read only mode + * @type {boolean} + */ + get isDisabled() { + return this.args.disabled; + } + + /** + * Returns true if the resource form is in edit mode and + * `edit` button is enabled for the secret field. + * This state lets the user to update the secret fields if they like + * @type {boolean} + */ + get isActionable() { + return this.args.showEditButton && !this.editing; + } + + // =actions + + /** + * Sets the secret field to be updated + * when `edit` button is clicked in Actionable view + */ + @action + enableEdit() { + if (!this.args.disabled) this.editing = true; + } + + /** + * Clears updated secret when cancel button is + * clicked in Actionable view. + * Sets the secret field back to disabled mode + */ + @action + clearEdit() { + this.secret = null; + this.editing = false; + } +} diff --git a/ui/admin/app/components/form/storage-bucket/index.hbs b/ui/admin/app/components/form/storage-bucket/index.hbs index 2413fd29f..3746791c9 100644 --- a/ui/admin/app/components/form/storage-bucket/index.hbs +++ b/ui/admin/app/components/form/storage-bucket/index.hbs @@ -164,29 +164,58 @@ {{/if}} - - {{t 'resources.storage-bucket.form.access_key_id.label'}} - {{t - 'resources.storage-bucket.form.access_key_id.help' - }} - {{#if @model.errors.access_key_id}} - - {{#each @model.errors.access_key_id as |error|}} - {{error.message}} - {{/each}} - - {{/if}} - - + {{#if @model.isNew}} + + {{t + 'resources.storage-bucket.form.access_key_id.label' + }} + {{t + 'resources.storage-bucket.form.access_key_id.help' + }} + {{#if @model.errors.access_key_id}} + + {{#each @model.errors.access_key_id as |error|}} + {{error.message}} + {{/each}} + + {{/if}} + + {{else}} + + {{t + 'resources.storage-bucket.form.access_key_id.label' + }} + {{t + 'resources.storage-bucket.form.access_key_id.help' + }} + {{#if @model.errors.access_key_id}} + + {{#each @model.errors.access_key_id as |error|}} + {{error.message}} + {{/each}} + + {{/if}} + + {{/if}} Date: Mon, 20 Mar 2023 23:14:03 +0530 Subject: [PATCH 050/193] =?UTF-8?q?chore:=20=F0=9F=A4=96=20style?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ui/admin/app/components/form/field/secret-input/index.hbs | 7 ++++++- ui/admin/app/components/form/field/secret-input/index.js | 2 +- ui/admin/app/components/form/storage-bucket/index.hbs | 2 ++ ui/admin/app/styles/app.scss | 1 + 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/ui/admin/app/components/form/field/secret-input/index.hbs b/ui/admin/app/components/form/field/secret-input/index.hbs index 1130a2fe4..95b7235e8 100644 --- a/ui/admin/app/components/form/field/secret-input/index.hbs +++ b/ui/admin/app/components/form/field/secret-input/index.hbs @@ -28,9 +28,14 @@ {{else}} - + {{/if}}
\ No newline at end of file diff --git a/ui/admin/app/components/form/field/secret-input/index.js b/ui/admin/app/components/form/field/secret-input/index.js index d07ef164b..a83b5a16b 100644 --- a/ui/admin/app/components/form/field/secret-input/index.js +++ b/ui/admin/app/components/form/field/secret-input/index.js @@ -52,7 +52,7 @@ export default class FormFieldSecretInputIndexComponent extends Component { * Sets the secret field back to disabled mode */ @action - clearEdit() { + cancelEdit() { this.secret = null; this.editing = false; } diff --git a/ui/admin/app/components/form/storage-bucket/index.hbs b/ui/admin/app/components/form/storage-bucket/index.hbs index 3746791c9..5c92f882b 100644 --- a/ui/admin/app/components/form/storage-bucket/index.hbs +++ b/ui/admin/app/components/form/storage-bucket/index.hbs @@ -189,6 +189,7 @@ {{/if}} + {{else}} {{/if}} + {{/if}} Date: Mon, 20 Mar 2023 23:15:16 +0530 Subject: [PATCH 051/193] =?UTF-8?q?chore:=20=F0=9F=A4=96=20undo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- addons/api/mirage/config.js | 1 + 1 file changed, 1 insertion(+) diff --git a/addons/api/mirage/config.js b/addons/api/mirage/config.js index 3b6781c0a..29c98b72a 100644 --- a/addons/api/mirage/config.js +++ b/addons/api/mirage/config.js @@ -677,6 +677,7 @@ function routes() { name: plugin_name, }; } + // Remove the secrets and add the hmac in the response delete attrs.secrets; attrs.secrets_hmac = faker.git.commitSha(); From a829727b1b569f82f6d3c181ab1ec32480af5367 Mon Sep 17 00:00:00 2001 From: Zhihe Li Date: Mon, 20 Mar 2023 14:06:15 -0400 Subject: [PATCH 052/193] Feat/update models (#128) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 🎸 Add mime types field * feat: 🎸 Add duration field to models --- .../generated/models/channel-recording.js | 12 +++++ .../generated/models/connection-recording.js | 19 +++++++ .../generated/models/session-recording.js | 12 +++++ addons/api/addon/transforms/duration.js | 40 +++++++++++++++ addons/api/app/transforms/duration.js | 1 + .../api/mirage/factories/channel-recording.js | 2 +- .../mirage/factories/connection-recording.js | 3 +- .../generated/factories/channel-recording.js | 2 + .../factories/connection-recording.js | 1 + .../generated/factories/session-recording.js | 1 + .../tests/unit/transforms/duration-test.js | 49 +++++++++++++++++++ 11 files changed, 140 insertions(+), 2 deletions(-) create mode 100644 addons/api/addon/transforms/duration.js create mode 100644 addons/api/app/transforms/duration.js create mode 100644 addons/api/tests/unit/transforms/duration-test.js diff --git a/addons/api/addon/generated/models/channel-recording.js b/addons/api/addon/generated/models/channel-recording.js index 841930aac..65e1a044b 100644 --- a/addons/api/addon/generated/models/channel-recording.js +++ b/addons/api/addon/generated/models/channel-recording.js @@ -50,4 +50,16 @@ export default class GeneratedChannelRecordingModel extends BaseModel { readOnly: true, }) finished_time; + + @attr({ + description: 'The array of mime types that this recording will support.', + readOnly: true, + }) + mime_types; + + @attr('duration', { + description: 'The duration of this channel recording in ms.', + readOnly: true, + }) + duration; } diff --git a/addons/api/addon/generated/models/connection-recording.js b/addons/api/addon/generated/models/connection-recording.js index 867b20c91..e78f77b8b 100644 --- a/addons/api/addon/generated/models/connection-recording.js +++ b/addons/api/addon/generated/models/connection-recording.js @@ -12,6 +12,13 @@ import { attr } from '@ember-data/model'; export default class GeneratedConnectionRecordingModel extends BaseModel { // =attributes + @attr('string', { + description: + 'The ID of the Connection which this Connection Recording recorded.', + readOnly: true, + }) + connection_id; + @attr('number', { description: 'The total number of bytes uploaded from the client in this Connection.', @@ -44,4 +51,16 @@ export default class GeneratedConnectionRecordingModel extends BaseModel { readOnly: true, }) finished_time; + + @attr({ + description: 'The array of mime types that this recording will support.', + readOnly: true, + }) + mime_types; + + @attr('duration', { + description: 'The duration of this connection recording in ms.', + readOnly: true, + }) + duration; } diff --git a/addons/api/addon/generated/models/session-recording.js b/addons/api/addon/generated/models/session-recording.js index 234f5acb0..b52c7370b 100644 --- a/addons/api/addon/generated/models/session-recording.js +++ b/addons/api/addon/generated/models/session-recording.js @@ -80,4 +80,16 @@ export default class GeneratedSessionRecordingModel extends BaseModel { readOnly: true, }) delete_on; + + @attr({ + description: 'The array of mime types that this recording will support.', + readOnly: true, + }) + mime_types; + + @attr('duration', { + description: 'The duration of this session recording in ms.', + readOnly: true, + }) + duration; } diff --git a/addons/api/addon/transforms/duration.js b/addons/api/addon/transforms/duration.js new file mode 100644 index 000000000..153a46025 --- /dev/null +++ b/addons/api/addon/transforms/duration.js @@ -0,0 +1,40 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import Transform from '@ember-data/serializer/transform'; + +export default class DurationTransform extends Transform { + /** + * Normalize a duration string in the format "3.0001s" to milliseconds. + * The backend returns a precision of nanoseconds but we round to whole + * milliseconds to avoid any issues with floating point math. + * @param serialized + * @returns {number} + */ + deserialize(serialized) { + if (!serialized) return 0; + const duration = serialized.split('s')[0]; + return Math.round(parseFloat(duration) * 1000); + } + + /** + * Serialize a duration in ms to a string in seconds. + * @param deserialized + * @returns {string} + */ + serialize(deserialized) { + if (!deserialized) return '0s'; + const durationInSeconds = deserialized / 1000; + + // We use `toLocaleString` to handle scenarios with very large numbers or + // very small numbers which will be represented as exponents. + // We force the max number of fraction digits to match the precision of the + // backend which is in nanoseconds. + return `${durationInSeconds.toLocaleString('fullwide', { + useGrouping: false, + maximumFractionDigits: 9, + })}s`; + } +} diff --git a/addons/api/app/transforms/duration.js b/addons/api/app/transforms/duration.js new file mode 100644 index 000000000..3c3dd0cc5 --- /dev/null +++ b/addons/api/app/transforms/duration.js @@ -0,0 +1 @@ +export { default } from 'api/transforms/duration'; diff --git a/addons/api/mirage/factories/channel-recording.js b/addons/api/mirage/factories/channel-recording.js index 3880e60d6..685b08115 100644 --- a/addons/api/mirage/factories/channel-recording.js +++ b/addons/api/mirage/factories/channel-recording.js @@ -8,6 +8,6 @@ import generateId from '../helpers/id'; import { TYPES_CHANNEL_RECORDING as types } from 'api/models/channel-recording'; export default factory.extend({ - id: () => generateId('srcc_'), + id: () => generateId('chr_'), type: (i) => types[i % types.length], }); diff --git a/addons/api/mirage/factories/connection-recording.js b/addons/api/mirage/factories/connection-recording.js index 13619fa22..148a7fedf 100644 --- a/addons/api/mirage/factories/connection-recording.js +++ b/addons/api/mirage/factories/connection-recording.js @@ -7,5 +7,6 @@ import factory from '../generated/factories/connection-recording'; import generateId from '../helpers/id'; export default factory.extend({ - id: () => generateId('src_'), + id: () => generateId('cr_'), + connection_id: () => generateId('sc_'), }); diff --git a/addons/api/mirage/generated/factories/channel-recording.js b/addons/api/mirage/generated/factories/channel-recording.js index 8c9602e57..75b0b0c5b 100644 --- a/addons/api/mirage/generated/factories/channel-recording.js +++ b/addons/api/mirage/generated/factories/channel-recording.js @@ -17,4 +17,6 @@ export default Factory.extend({ return faker.date.recent(3, this.finished_time); }, finished_time: () => faker.date.recent(), + duration: () => `${faker.datatype.number()}s`, + mime_types: () => ['application/x-asciicast'], }); diff --git a/addons/api/mirage/generated/factories/connection-recording.js b/addons/api/mirage/generated/factories/connection-recording.js index 3f9eb3452..17f7b1583 100644 --- a/addons/api/mirage/generated/factories/connection-recording.js +++ b/addons/api/mirage/generated/factories/connection-recording.js @@ -17,4 +17,5 @@ export default Factory.extend({ return faker.date.recent(3, this.finished_time); }, finished_time: () => faker.date.recent(), + duration: () => `${faker.datatype.number()}s`, }); diff --git a/addons/api/mirage/generated/factories/session-recording.js b/addons/api/mirage/generated/factories/session-recording.js index 731e3dc3b..07032faf3 100644 --- a/addons/api/mirage/generated/factories/session-recording.js +++ b/addons/api/mirage/generated/factories/session-recording.js @@ -21,4 +21,5 @@ export default Factory.extend({ }, updated_time: () => faker.date.recent(), deleted_on: () => faker.date.soon(), + duration: () => `${faker.datatype.number()}s`, }); diff --git a/addons/api/tests/unit/transforms/duration-test.js b/addons/api/tests/unit/transforms/duration-test.js new file mode 100644 index 000000000..35027c50e --- /dev/null +++ b/addons/api/tests/unit/transforms/duration-test.js @@ -0,0 +1,49 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Transform | duration', function (hooks) { + setupTest(hooks); + + test('it deserializes a duration string', function (assert) { + assert.expect(8); + const transform = this.owner.lookup('transform:duration'); + + const num1 = transform.deserialize('0s'); + const num2 = transform.deserialize(undefined); + const num3 = transform.deserialize('3s'); + const num4 = transform.deserialize('15.003s'); + const num5 = transform.deserialize('15.0035s'); + const num6 = transform.deserialize('15.0034s'); + const num7 = transform.deserialize('3.000000001s'); + const num8 = transform.deserialize('300000000001s'); + + assert.strictEqual(num1, 0); + assert.strictEqual(num2, 0); + assert.strictEqual(num3, 3000); + assert.strictEqual(num4, 15003); + assert.strictEqual(num5, 15004); + assert.strictEqual(num6, 15003); + assert.strictEqual(num7, 3000); + assert.strictEqual(num8, 300000000001000); + }); + + test('it serializes a duration number', function (assert) { + assert.expect(7); + const transform = this.owner.lookup('transform:duration'); + const num1 = transform.serialize(0); + const num2 = transform.serialize(undefined); + const num3 = transform.serialize(3000); + const num4 = transform.serialize(15003); + const num5 = transform.serialize(15000000000001); + const num6 = transform.serialize(0.000001); + const num7 = transform.serialize(0.0000001); + + assert.strictEqual(num1, '0s'); + assert.strictEqual(num2, '0s'); + assert.strictEqual(num3, '3s'); + assert.strictEqual(num4, '15.003s'); + assert.strictEqual(num5, '15000000000.001s'); + assert.strictEqual(num6, '0.000000001s'); + assert.strictEqual(num7, '0s'); + }); +}); From 5984a60ae1dd528214ace83e0d744a476ff2e652 Mon Sep 17 00:00:00 2001 From: dharini Date: Mon, 20 Mar 2023 23:36:27 +0530 Subject: [PATCH 053/193] =?UTF-8?q?chore:=20=F0=9F=A4=96=20scss=20lint?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ui/admin/app/styles/app.scss | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ui/admin/app/styles/app.scss b/ui/admin/app/styles/app.scss index 6f32c221a..474afc396 100644 --- a/ui/admin/app/styles/app.scss +++ b/ui/admin/app/styles/app.scss @@ -695,6 +695,7 @@ .hds-form-text-input { width: 99%; + &::placeholder { content: ''; width: 80%; @@ -704,11 +705,13 @@ vertical-align: middle; } } + .hds-button { margin-top: 4.25rem; width: 6rem; } } + // session recording player .session-recording-player { --player-background-color: #252937; From 57d31d4ccf300c09f407ad97ce52a15e157e672a Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Date: Mon, 20 Mar 2023 13:27:24 -0700 Subject: [PATCH 054/193] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20Session=20record?= =?UTF-8?q?ings=20list?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add session recordings list βœ… Closes: ICU-8419 --- addons/core/translations/resources/en-us.yaml | 9 +++ ui/admin/app/formats.js | 7 ++ ui/admin/app/styles/app.scss | 11 +++ .../scopes/scope/session-recordings/index.hbs | 69 ++++++++++++++++--- 4 files changed, 86 insertions(+), 10 deletions(-) diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml index 9f2fb54f8..1deee0f25 100644 --- a/addons/core/translations/resources/en-us.yaml +++ b/addons/core/translations/resources/en-us.yaml @@ -222,6 +222,15 @@ session-recording: title_plural: Channels session: title: Session Playback + form: + time: + label: Time + user: + label: User + target: + label: Target + duration: + label: Duration storage-bucket: title: Storage Bucket title_plural: Storage Buckets diff --git a/ui/admin/app/formats.js b/ui/admin/app/formats.js index 3d6cb9a0b..197e8f054 100644 --- a/ui/admin/app/formats.js +++ b/ui/admin/app/formats.js @@ -34,6 +34,13 @@ export default { minute: 'numeric', timeZoneName: 'short', }, + mmddyyhhmm: { + year: 'numeric', + month: '2-digit', + day: '2-digit', + hour: 'numeric', + minute: 'numeric', + }, }, number: { compact: { notation: 'compact' }, diff --git a/ui/admin/app/styles/app.scss b/ui/admin/app/styles/app.scss index c1bc62db0..cf263297c 100644 --- a/ui/admin/app/styles/app.scss +++ b/ui/admin/app/styles/app.scss @@ -776,3 +776,14 @@ 'sidebar'; } } + +// Session recording - List +.session-recording-list-cell-item { + display: flex; + gap: sizing.rems(xs); + + span { + display: flex; + align-items: center; + } +} diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs index 5762bc212..8d423682f 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs @@ -4,15 +4,64 @@ - {{#each @model as |recording|}} -

- - {{recording.id}} - -

- {{/each}} + {{#if @model}} + + <:body as |B|> + + + + {{format-date B.data.started_time format='mmddyyhhmm'}} + + + +
+ + {{B.data.user.name}} +
+
+ +
+ + {{B.data.target.name}} +
+
+ +
+ + + {{format-time-duration B.data.duration}} + +
+
+ + + +
+ +
+ {{/if}}
\ No newline at end of file From c08c9cc50de3feaba3a1a20207b10a2c782bdcb4 Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Date: Mon, 20 Mar 2023 14:13:46 -0700 Subject: [PATCH 055/193] Change typographies within table --- .../scopes/scope/session-recordings/index.hbs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs index 8d423682f..4807d684e 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs @@ -24,19 +24,19 @@ -
+
- {{B.data.user.name}} + {{B.data.user.name}}
-
+
- {{B.data.target.name}} + {{B.data.target.name}}
From 0d47a37cdfdc17d610f34d774641c7c991764369 Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Date: Mon, 20 Mar 2023 14:20:11 -0700 Subject: [PATCH 056/193] Add breadcrumbs --- .../scopes/scope/session-recordings.js | 16 ++++++++++++++++ .../scopes/scope/session-recordings/index.hbs | 4 ++++ .../scopes/scope/session-recordings-test.js | 13 +++++++++++++ 3 files changed, 33 insertions(+) create mode 100644 ui/admin/app/controllers/scopes/scope/session-recordings.js create mode 100644 ui/admin/tests/unit/controllers/scopes/scope/session-recordings-test.js diff --git a/ui/admin/app/controllers/scopes/scope/session-recordings.js b/ui/admin/app/controllers/scopes/scope/session-recordings.js new file mode 100644 index 000000000..d9ffc7fb0 --- /dev/null +++ b/ui/admin/app/controllers/scopes/scope/session-recordings.js @@ -0,0 +1,16 @@ +import Controller from '@ember/controller'; +import { inject as service } from '@ember/service'; + +export default class ScopesScopeSessionRecordingsController extends Controller { + // =services + + @service intl; + + //= attributes + /** + * Translated breadcrumb + */ + get breadCrumb() { + return this.intl.t('resources.session-recording.title_plural'); + } +} diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs index 4807d684e..8a7d8b86e 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs @@ -1,4 +1,8 @@ + + + +

{{t 'resources.session-recording.title_plural'}}

diff --git a/ui/admin/tests/unit/controllers/scopes/scope/session-recordings-test.js b/ui/admin/tests/unit/controllers/scopes/scope/session-recordings-test.js new file mode 100644 index 000000000..94159166b --- /dev/null +++ b/ui/admin/tests/unit/controllers/scopes/scope/session-recordings-test.js @@ -0,0 +1,13 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'admin/tests/helpers'; + +module('Unit | Controller | scopes/scope/session-recordings', function (hooks) { + setupTest(hooks); + + test('it exists', function (assert) { + let controller = this.owner.lookup( + 'controller:scopes/scope/session-recordings' + ); + assert.ok(controller); + }); +}); From 96b2bcd6ff143897685161ffbf14c995225c7626 Mon Sep 17 00:00:00 2001 From: dharini Date: Tue, 21 Mar 2023 14:42:54 +0530 Subject: [PATCH 057/193] =?UTF-8?q?fix:=20=F0=9F=90=9B=20style,=20remove?= =?UTF-8?q?=20comment?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/components/form/field/secret-input/index.js | 1 - ui/admin/app/styles/app.scss | 10 ++++------ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/ui/admin/app/components/form/field/secret-input/index.js b/ui/admin/app/components/form/field/secret-input/index.js index a83b5a16b..3a1876f7a 100644 --- a/ui/admin/app/components/form/field/secret-input/index.js +++ b/ui/admin/app/components/form/field/secret-input/index.js @@ -15,7 +15,6 @@ export default class FormFieldSecretInputIndexComponent extends Component { */ @tracked editing = false; @tracked secret; - // =actions /** * Returns true if the resource form is in read only mode diff --git a/ui/admin/app/styles/app.scss b/ui/admin/app/styles/app.scss index 474afc396..a93a83090 100644 --- a/ui/admin/app/styles/app.scss +++ b/ui/admin/app/styles/app.scss @@ -690,24 +690,22 @@ // secret input field .secret-input { display: flex; - align-items: flex-start; - justify-content: space-between; + align-items: flex-end; + column-gap: 0.5rem; .hds-form-text-input { - width: 99%; - &::placeholder { content: ''; width: 80%; height: 0.65rem; - background-color: var(--ui-gray-subtler-3); + background-color: var(--token-color-palette-neutral-200); border-radius: 0.25rem; vertical-align: middle; } } .hds-button { - margin-top: 4.25rem; + margin-bottom: 1.5rem; width: 6rem; } } From 3d6d474bd702697d0fde7608e9cf26a0f6a14e75 Mon Sep 17 00:00:00 2001 From: Zhihe Li Date: Tue, 21 Mar 2023 12:53:05 -0400 Subject: [PATCH 058/193] =?UTF-8?q?refactor:=20=F0=9F=92=A1=20Return=20all?= =?UTF-8?q?=20storage=20buckets=20from=20mirage=20(#135)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- addons/api/mirage/config.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/addons/api/mirage/config.js b/addons/api/mirage/config.js index 29c98b72a..69eb82f7a 100644 --- a/addons/api/mirage/config.js +++ b/addons/api/mirage/config.js @@ -658,12 +658,7 @@ function routes() { }); // storage-buckets - this.get( - '/storage-buckets', - ({ storageBuckets }, { queryParams: { scope_id: scopeId } }) => { - return storageBuckets.where({ scopeId }); - } - ); + this.get('/storage-buckets'); this.get('/storage-buckets/:id'); this.del('/storage-buckets/:id'); this.patch('/storage-buckets/:id'); From 774d9a8bff02fe3e8abb55831eb832d9c14bfae6 Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Date: Tue, 21 Mar 2023 10:38:19 -0700 Subject: [PATCH 059/193] Add acceptance test --- .../session-recordings/list-test.js | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 ui/admin/tests/acceptance/session-recordings/list-test.js diff --git a/ui/admin/tests/acceptance/session-recordings/list-test.js b/ui/admin/tests/acceptance/session-recordings/list-test.js new file mode 100644 index 000000000..b7c23f02b --- /dev/null +++ b/ui/admin/tests/acceptance/session-recordings/list-test.js @@ -0,0 +1,62 @@ +import { module, test } from 'qunit'; +import { visit, currentURL, click } from '@ember/test-helpers'; +import { setupApplicationTest } from 'admin/tests/helpers'; +import setupMirage from 'ember-cli-mirage/test-support/setup-mirage'; +import { authenticateSession } from 'ember-simple-auth/test-support'; + +module('Acceptance | session recordings | list', function (hooks) { + setupApplicationTest(hooks); + setupMirage(hooks); + + // Selectors + const LIST_SESSION_RECORDING_BUTTON = + 'table > tbody > tr > td:last-child > a'; + + const instances = { + scopes: { + global: null, + org: null, + }, + sessionRecording: null, + }; + + const urls = { + globalScope: null, + sessionRecordings: null, + sessionRecording: null, + }; + + hooks.beforeEach(function () { + instances.scopes.global = this.server.create('scope', { id: 'global' }); + instances.scopes.org = this.server.create('scope', { + type: 'org', + scope: { id: 'global', type: 'global' }, + }); + instances.sessionRecording = this.server.create('session-recording', { + scope: instances.scopes.global, + }); + urls.globalScope = `/scopes/global`; + urls.sessionRecordings = `${urls.globalScope}/session-recordings`; + urls.sessionRecording = `${urls.sessionRecordings}/${instances.sessionRecording.id}`; + authenticateSession({}); + }); + + // TODO: When we add abilities to session-recordings this test will be refactor to account for it. + test('users can to session-recordings', async function (assert) { + assert.expect(1); + // Visit session recordings + await visit(urls.sessionRecordings); + assert.strictEqual(currentURL(), urls.sessionRecordings); + }); + + // TODO: When we add abilities to session-recordings this test will be refactor to account for it. + test('user can navigate to a session recording', async function (assert) { + assert.expect(2); + // Visit session recordings + await visit(urls.sessionRecordings); + assert.dom('table').hasClass('hds-table'); + // Click a session recording and check it navigates properly + await click(LIST_SESSION_RECORDING_BUTTON); + assert.strictEqual(currentURL(), urls.sessionRecording); + }); +}); From 638fc9afdffaee0cedb054996f19ac9203dd8d91 Mon Sep 17 00:00:00 2001 From: lisbet-alvarez <107949262+lisbet-alvarez@users.noreply.github.com> Date: Tue, 21 Mar 2023 10:42:38 -0700 Subject: [PATCH 060/193] =?UTF-8?q?test:=20=F0=9F=92=8D=20acceptance=20tes?= =?UTF-8?q?ts=20for=20creation=20of=20a=20storage=20bucket=20(#131)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * test: πŸ’ create acceptance tests for storage buckets βœ… Closes: ICU-8239 --- .../storage-buckets/create-test-test.js | 132 ++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 ui/admin/tests/acceptance/storage-buckets/create-test-test.js diff --git a/ui/admin/tests/acceptance/storage-buckets/create-test-test.js b/ui/admin/tests/acceptance/storage-buckets/create-test-test.js new file mode 100644 index 000000000..edfcd044d --- /dev/null +++ b/ui/admin/tests/acceptance/storage-buckets/create-test-test.js @@ -0,0 +1,132 @@ +import { module, test } from 'qunit'; +import { visit, currentURL, click, fillIn } from '@ember/test-helpers'; +import { setupApplicationTest } from 'admin/tests/helpers'; +import setupMirage from 'ember-cli-mirage/test-support/setup-mirage'; +import a11yAudit from 'ember-a11y-testing/test-support/audit'; +import { Response } from 'miragejs'; +import { authenticateSession } from 'ember-simple-auth/test-support'; + +module('Acceptance | storage-buckets | create', function (hooks) { + setupApplicationTest(hooks); + setupMirage(hooks); + + let features; + let getStorageBucketCount; + + const SAVE_BTN_SELECTOR = '[type="submit"]'; + const CANCEL_BTN_SELECTOR = '.rose-form-actions [type="button"]'; + const NAME_FIELD_SELECTOR = '[name="name"]'; + const ALERT_TEXT_SELECTOR = '[role="alert"] div'; + const FIELD_ERROR_TEXT_SELECTOR = '.hds-form-error__message'; + const NAME_FIELD_TEXT = 'random string'; + + const instances = { + scopes: { + global: null, + org: null, + }, + }; + + const urls = { + globalScope: null, + storageBuckets: null, + newStorageBucket: null, + }; + + hooks.beforeEach(function () { + instances.scopes.global = this.server.create('scope', { id: 'global' }); + instances.scopes.org = this.server.create('scope', { + type: 'org', + scope: { id: 'global', type: 'global' }, + }); + urls.globalScope = `/scopes/global`; + urls.storageBuckets = `${urls.globalScope}/storage-buckets`; + urls.newStorageBucket = `${urls.storageBuckets}/new`; + getStorageBucketCount = () => + this.server.schema.storageBuckets.all().models.length; + + features = this.owner.lookup('service:features'); + features.enable('session-recording'); + authenticateSession({}); + }); + + test('users can create a new storage bucket with global scope', async function (assert) { + assert.expect(3); + const storageBucketCount = getStorageBucketCount(); + await visit(urls.storageBuckets); + + await click(`[href="${urls.newStorageBucket}"]`); + await fillIn(NAME_FIELD_SELECTOR, NAME_FIELD_TEXT); + await click('[value="global"]'); + await click(SAVE_BTN_SELECTOR); + const storageBucket = this.server.schema.storageBuckets.findBy({ + name: NAME_FIELD_TEXT, + }); + + assert.strictEqual(storageBucket.name, NAME_FIELD_TEXT); + assert.strictEqual(storageBucket.scopeId, 'global'); + assert.strictEqual(getStorageBucketCount(), storageBucketCount + 1); + }); + + test('users can create a new storage bucket with org scope', async function (assert) { + assert.expect(3); + const storageBucketCount = getStorageBucketCount(); + await visit(urls.storageBuckets); + + await click(`[href="${urls.newStorageBucket}"]`); + await fillIn(NAME_FIELD_SELECTOR, NAME_FIELD_TEXT); + await click(`[value="${instances.scopes.org.scope.id}"]`); + await click(SAVE_BTN_SELECTOR); + const storageBucket = this.server.schema.storageBuckets.findBy({ + name: NAME_FIELD_TEXT, + }); + + assert.strictEqual(storageBucket.name, NAME_FIELD_TEXT); + assert.strictEqual(storageBucket.scopeId, instances.scopes.org.scope.id); + assert.strictEqual(getStorageBucketCount(), storageBucketCount + 1); + }); + + test('user can cancel new storage bucket creation', async function (assert) { + assert.expect(2); + const storageBucketCount = getStorageBucketCount(); + await visit(urls.storageBuckets); + + await click(`[href="${urls.newStorageBucket}"]`); + await fillIn(NAME_FIELD_SELECTOR, NAME_FIELD_TEXT); + await click(CANCEL_BTN_SELECTOR); + + assert.strictEqual(currentURL(), urls.storageBuckets); + assert.strictEqual(getStorageBucketCount(), storageBucketCount); + }); + + test('saving a new storage bucket with invalid fields displays error messages', async function (assert) { + assert.expect(2); + this.server.post('/storage-buckets', () => { + return new Response( + 400, + {}, + { + status: 400, + code: 'invalid_argument', + message: 'The request was invalid.', + details: { + request_fields: [ + { + name: 'name', + description: 'Name is required.', + }, + ], + }, + } + ); + }); + await visit(urls.storageBuckets); + + await click(`[href="${urls.newStorageBucket}"]`); + await click(SAVE_BTN_SELECTOR); + await a11yAudit(); + + assert.dom(ALERT_TEXT_SELECTOR).hasText('The request was invalid.'); + assert.dom(FIELD_ERROR_TEXT_SELECTOR).hasText('Name is required.'); + }); +}); From a364407b27f12a408d46da4ccaa5bccf0c4887d7 Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Date: Tue, 21 Mar 2023 10:43:18 -0700 Subject: [PATCH 061/193] Typo --- ui/admin/tests/acceptance/session-recordings/list-test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/admin/tests/acceptance/session-recordings/list-test.js b/ui/admin/tests/acceptance/session-recordings/list-test.js index b7c23f02b..ebeca115a 100644 --- a/ui/admin/tests/acceptance/session-recordings/list-test.js +++ b/ui/admin/tests/acceptance/session-recordings/list-test.js @@ -42,7 +42,7 @@ module('Acceptance | session recordings | list', function (hooks) { }); // TODO: When we add abilities to session-recordings this test will be refactor to account for it. - test('users can to session-recordings', async function (assert) { + test('users can navigate to session-recordings', async function (assert) { assert.expect(1); // Visit session recordings await visit(urls.sessionRecordings); From 1e7268ff5404c863e7973a1c7bbb3157b2650608 Mon Sep 17 00:00:00 2001 From: Zhihe Li Date: Tue, 21 Mar 2023 15:52:58 -0400 Subject: [PATCH 062/193] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20Add=20mirage=20d?= =?UTF-8?q?ata=20for=20ascii=20casts=20and=20use=20fetch=20(#129)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 🎸 Add mirage data for ascii casts and use fetch βœ… Closes: ICU-8189 --- .../api/addon/adapters/session-recording.js | 55 +++++++ addons/api/addon/models/channel-recording.js | 9 ++ addons/api/addon/models/session-recording.js | 22 --- addons/api/app/adapters/session-recording.js | 1 + addons/api/mirage/config.js | 15 +- addons/api/mirage/data/asciicasts.js | 151 ++++++++++++++++++ .../unit/adapters/session-recording-test.js | 42 +++++ 7 files changed, 272 insertions(+), 23 deletions(-) create mode 100644 addons/api/addon/adapters/session-recording.js create mode 100644 addons/api/app/adapters/session-recording.js create mode 100644 addons/api/mirage/data/asciicasts.js create mode 100644 addons/api/tests/unit/adapters/session-recording-test.js diff --git a/addons/api/addon/adapters/session-recording.js b/addons/api/addon/adapters/session-recording.js new file mode 100644 index 000000000..0531baa3a --- /dev/null +++ b/addons/api/addon/adapters/session-recording.js @@ -0,0 +1,55 @@ +import ApplicationAdapter from './application'; + +export default class SessionRecordingAdapter extends ApplicationAdapter { + /** + * Overrides the default `buildURL` such that for custom download methods, + * URLs will get the query parameters. All other request types behave as normal. + * + * @param modelName {string} + * @param id {string} + * @param snapshot {object} + * @param requestType {string} + * @param query {object} + * @returns {string} + */ + buildURL(modelName, id, snapshot, requestType, query) { + let url = super.buildURL(...arguments); + const method = snapshot?.adapterOptions?.method; + if (method === 'download') { + const queryParams = new URLSearchParams(query).toString(); + if (queryParams) url = `${url}?${queryParams}`; + } + return url; + } + + /** + * Handles the download recording for recordings. Takes in a mime type for the + * type or recording to return. + * The ID can be the session ID, session recording ID, + * connection recording ID, or the channel recording ID. + * @param id {string} + * @param mimeType {string} + * @returns {Promise} + */ + async getRecordingDownload({ id, mimeType }) { + const options = { adapterOptions: { method: 'download' } }; + const url = this.buildURL('session-recording', id, options, 'findRecord', { + mime_type: mimeType, + }); + + const response = await fetch(url); + return response.text(); + } + + /** + * Returns an ascii cast recording. + * @param id + * @returns {Promise} + */ + getAsciicast(id) { + return this.getRecordingDownload({ + id, + mimeType: 'application/x-asciicast', + }); + } +} diff --git a/addons/api/addon/models/channel-recording.js b/addons/api/addon/models/channel-recording.js index 6652b11fe..42c459170 100644 --- a/addons/api/addon/models/channel-recording.js +++ b/addons/api/addon/models/channel-recording.js @@ -24,4 +24,13 @@ export default class ChannelRecordingModel extends GeneratedChannelRecordingMode get isUnknown() { return !TYPES_CHANNEL_RECORDING.includes(this.type); } + + /** + * Download the ascii cast recording for this channel. + * @returns {Promise} + */ + getAsciicast() { + const adapter = this.store.adapterFor('session-recording'); + return adapter.getAsciicast(this.id); + } } diff --git a/addons/api/addon/models/session-recording.js b/addons/api/addon/models/session-recording.js index c1d8a4d83..db0714b51 100644 --- a/addons/api/addon/models/session-recording.js +++ b/addons/api/addon/models/session-recording.js @@ -27,26 +27,4 @@ export default class SessionRecordingModel extends GeneratedSessionRecordingMode get isUnknown() { return !TYPES_SESSION_RECORDING.includes(this.type); } - - /** - * Download the recording for either session, connection, or channels. - * id can be the session ID, session recording ID, connection recording ID, - * or the channel recording ID. - * @param {string} id - * @param {string} mimeType - * @returns {Promise} - */ - getAsciiCast(id) { - const adapter = this.store.adapterFor('application'); - const options = { adapterOptions: { method: 'download' } }; - const url = adapter.buildURL( - 'session-recording', - id, - options, - 'findRecord' - ); - return adapter.ajax(url, 'GET', { - data: { mimeType: 'application/x-asciicast' }, - }); - } } diff --git a/addons/api/app/adapters/session-recording.js b/addons/api/app/adapters/session-recording.js new file mode 100644 index 000000000..b8c3a26ce --- /dev/null +++ b/addons/api/app/adapters/session-recording.js @@ -0,0 +1 @@ +export { default } from 'api/adapters/session-recording'; diff --git a/addons/api/mirage/config.js b/addons/api/mirage/config.js index 69eb82f7a..e2a31192f 100644 --- a/addons/api/mirage/config.js +++ b/addons/api/mirage/config.js @@ -15,6 +15,7 @@ import { pickRandomStatusString } from './factories/session'; import initializeMockIPC from './scenarios/ipc'; import makeBooleanFilter from './helpers/bexpr-filter'; import { faker } from '@faker-js/faker'; +import { asciiCasts } from './data/asciicasts'; const isTesting = environmentConfig.environment === 'test'; @@ -688,7 +689,19 @@ function routes() { return sessionRecordings.where({ scopeId }); } ); - this.get('/session-recordings/:id'); + this.get( + '/session-recordings/:idMethod', + async ({ sessionRecordings }, { params: { idMethod } }) => { + const id = idMethod.split(':')[0]; + const method = idMethod.split(':')[1]; + + if (method === 'download') { + return faker.helpers.arrayElement(asciiCasts); + } else { + return sessionRecordings.find(id); + } + } + ); /* Uncomment the following line and the Response import above * Then change the response code to simulate error responses. diff --git a/addons/api/mirage/data/asciicasts.js b/addons/api/mirage/data/asciicasts.js new file mode 100644 index 000000000..99ce39286 --- /dev/null +++ b/addons/api/mirage/data/asciicasts.js @@ -0,0 +1,151 @@ +export const asciiCast1 = `{"version": 2, "width": 124, "height": 36, "timestamp": 1670352594, "env": {"SHELL": "/bin/zsh", "TERM": "xterm-256color"}} +[2.138652, "o", "\\u001b[1m\\u001b[7m%\\u001b[27m\\u001b[1m\\u001b[0m \\r \\r\\u001b]2;ember-asciinema-player\\u0007\\u001b]1;..iinema-player\\u0007"] +[2.220877, "o", "\\r\\u001b[0m\\u001b[27m\\u001b[24m\\u001b[J\\u001b[33member-asciinema-player\\u001b[00m \\u001b[32mgit\\u001b[00m:\\u001b[36m(main*)\\u001b[00m $ \\u001b[K"] +[2.221019, "o", "\\u001b[?1h\\u001b="] +[2.221076, "o", "\\u001b[?2004h"] +[2.676444, "o", "y"] +[2.788653, "o", "\\bya"] +[2.868652, "o", "r"] +[3.001764, "o", "n"] +[3.167636, "o", " "] +[3.313668, "o", "t"] +[3.460527, "o", "e"] +[3.561983, "o", "s"] +[3.63678, "o", "t"] +[3.853437, "o", "\\u001b[?1l\\u001b>"] +[3.853473, "o", "\\u001b[?2004l\\r\\r\\n"] +[3.854604, "o", "\\u001b]2;yarn test\\u0007\\u001b]1;yarn\\u0007"] +[4.489178, "o", "\\u001b[2K"] +[4.48982, "o", "\\u001b[1G\\u001b[1myarn run v1.22.19\\u001b[22m\\r\\n"] +[4.555618, "o", "\\u001b[2K"] +[4.555649, "o", "\\u001b[1G\\u001b[2m$ npm-run-all lint\\u001b[22m\\r\\n"] +[5.345253, "o", "\\u001b[2K"] +[5.345509, "o", "\\u001b[1G\\u001b[2m$ npm-run-all --print-name --aggregate-output --continue-on-error --parallel \\"lint:!(fix)\\"\\u001b[22m\\r\\n"] +[7.225926, "o", "\\r\\n> ember-asciinema-player@0.0.0 lint:js ember-asciinema-player/package.json\\r\\n> eslint . --cache \\r\\n\\r\\n$ eslint . --cache\\r\\n"] +[8.398641, "o", "\\r\\n> ember-asciinema-player@0.0.0 lint:hbs ember-asciinema-player/package.json\\r\\n> ember-template-lint . \\r\\n\\r\\n$ ember-template-lint .\\r\\n\\r\\n"] +[8.418537, "o", "\\u001b[2K\\u001b[1G\\u001b[2m$ ember test\\u001b[22m\\r\\n"] +[12.256156, "o", "\\u001b[?25l"] +[12.256464, "o", "\\u001b[32mβ ‹\\u001b[39m \\u001b[32mBuilding\\u001b[39m"] +[12.2573, "o", "\\u001b[2K"] +[12.257386, "o", "\\u001b[1G\\u001b[?25h"] +[12.257689, "o", "Environment: test\\r\\n"] +[12.257857, "o", "\\u001b[?25l\\u001b[32mβ ‹\\u001b[39m \\u001b[32mBuilding\\u001b[39m"] +[12.539035, "o", "\\u001b[2K"] +[12.539144, "o", "\\u001b[1G"] +[12.539219, "o", "\\u001b[32mβ ™\\u001b[39m \\u001b[32mbuilding... \\u001b[39m"] +[12.745202, "o", "\\u001b[2K\\u001b[1G"] +[12.745343, "o", "\\u001b[32mβ Ή\\u001b[39m \\u001b[32mbuilding... \\u001b[39m[Babel: @ember/test-helpers > applyPatches]"] +[12.825004, "o", "\\u001b[2K"] +[12.825031, "o", "\\u001b[1G"] +[12.825122, "o", "\\u001b[32mβ Έ\\u001b[39m \\u001b[32mbuilding... \\u001b[39m[Babel: ember-qunit > applyPatches]"] +[12.933588, "o", "\\u001b[2K\\u001b[1G"] +[12.933624, "o", "\\u001b[32mβ Ό\\u001b[39m \\u001b[32mbuilding... \\u001b[39m[Babel: ember-load-initializers > applyPatches]"] +[13.194738, "o", "\\u001b[2K\\u001b[1G"] +[13.195009, "o", "\\u001b[32mβ ΄\\u001b[39m \\u001b[32mbuilding... \\u001b[39m[Babel: ember-asciinema-player > applyPatches]"] +[13.307878, "o", "\\u001b[2K\\u001b[1G\\u001b[32mβ ¦\\u001b[39m \\u001b[32mbuilding... \\u001b[39m[Package /assets/vendor.js]"] +[13.750717, "o", "\\u001b[2K\\u001b[1G"] +[13.750755, "o", "\\u001b[32mβ §\\u001b[39m \\u001b[32mbuilding... \\u001b[39m[Concat: Test Support JS]"] +[13.869411, "o", "\\u001b[2K\\u001b[1G"] +[13.869438, "o", "\\u001b[32mβ ‡\\u001b[39m \\u001b[32mbuilding... \\u001b[39m[ember-auto-import-webpack]"] +[14.655374, "o", "\\u001b[2K\\u001b[1G"] +[14.655415, "o", "\\u001b[32m⠏\\u001b[39m \\u001b[32mbuilding... \\u001b[39m[ember-auto-import-webpack]"] +[14.73686, "o", "\\u001b[2K\\u001b[1G\\u001b[?25h"] +[14.738533, "o", "\\u001b[?25h"] +[14.738818, "o", "\\u001b[?25l\\u001b[32mβ ‹\\u001b[39m cleaning up"] +[14.739061, "o", "\\u001b[2K\\u001b[1G\\u001b[?25hcleaning up...\\r\\n"] +[14.739197, "o", "\\u001b[?25l\\u001b[32mβ ‹\\u001b[39m cleaning up"] +[14.907985, "o", "\\u001b[2K"] +[14.90808, "o", "\\u001b[1G\\u001b[?25h"] +[14.908128, "o", "\\u001b[32mBuilt project successfully.\\u001b[39m\\r\\n"] +[16.224632, "o", "ok 1 Chrome 108.0 - [2 ms] - ember-qunit: Ember.onerror validation: Ember.onerror is functioning properly\\r\\n"] +[16.346568, "o", "\\r\\n1..1\\r\\n# tests 1\\r\\n# pass 1\\r\\n# skip 0\\r\\n# todo 0\\r\\n# fail 0\\r\\n\\r\\n# ok\\r\\n"] +[16.403167, "o", "\\u001b[2K"] +[16.403388, "o", "\\u001b[1G✨ Done in 11.92s.\\r\\n"] +[16.413967, "o", "\\u001b[1m\\u001b[7m%\\u001b[27m\\u001b[1m\\u001b[0m \\r \\r"] +[16.414147, "o", "\\u001b]2;ember-asciinema-player\\u0007\\u001b]1;..iinema-player\\u0007"] +[16.528341, "o", "\\r\\u001b[0m\\u001b[27m\\u001b[24m\\u001b[J\\u001b[33member-asciinema-player\\u001b[00m \\u001b[32mgit\\u001b[00m:\\u001b[36m(main*)\\u001b[00m $ \\u001b[K"] +[16.528501, "o", "\\u001b[?1h\\u001b="] +[16.52863, "o", "\\u001b[?2004h"] +[19.078794, "o", "\\u001b[?2004l\\r\\r\\n"]`; + +export const asciiCast2 = `{"version": 2, "width": 112, "height": 30, "timestamp": 1672793720, "env": {"SHELL": "/bin/bash", "TERM": "xterm-256color"}} +[0.036928, "o", "\\u001b[?2004h\\u001b[1;32m[\\u001b]0;johan@nixos: ~/src/hashicorp/boundary-enterprise\\u0007johan@nixos:~/src/hashicorp/boundary-enterprise]$\\u001b[0m "] +[2.827983, "o", "b"] +[2.9386, "o", "o"] +[2.97036, "o", "u"] +[3.032542, "o", "n"] +[3.108687, "o", "d"] +[3.246045, "o", "a"] +[3.340117, "o", "r"] +[3.841216, "o", "y"] +[4.314958, "o", " "] +[6.052102, "o", "u"] +[6.146486, "o", "s"] +[6.207341, "o", "e"] +[6.273087, "o", "r"] +[6.378873, "o", "s"] +[6.799687, "o", " "] +[7.08347, "o", "l"] +[7.159196, "o", "i"] +[7.249656, "o", "s"] +[7.352251, "o", "t"] +[7.450038, "o", " "] +[7.688195, "o", "-"] +[7.931818, "o", "r"] +[8.001542, "o", "e"] +[8.387771, "o", "c"] +[8.526339, "o", "u"] +[8.631438, "o", "r"] +[8.81899, "o", "s"] +[8.958184, "o", "i"] +[9.085688, "o", "v"] +[9.134885, "o", "e"] +[9.786868, "o", "\\r\\n"] +[9.788828, "o", "\\u001b[?2004l\\r"] +[10.086691, "o", "\\u001b[0m\\r\\nUser information:\\r\\n ID: u_anon\\r\\n Scope ID: global\\r\\n Version: 1\\r\\n Name: anonymous\\r\\n Description: The anonymous user matches any request, whether authenticated or not\\r\\n Authorized Actions:\\r\\n no-op\\r\\n read\\r\\n update\\r\\n delete\\r\\n add-accounts\\r\\n set-accounts\\r\\n remove-accounts\\r\\n\\r\\n ID: u_auth\\r\\n Scope ID: global\\r\\n Version: 1\\r\\n Name: authenticated\\r\\n Description: The authenticated user matches any user that has a valid token\\r\\n Authorized Actions:\\r\\n no-op\\r\\n read\\r\\n update\\r\\n delete\\r\\n add-accounts\\r\\n set-accounts\\r\\n remove-accounts\\r\\n\\r\\n ID: u_recovery\\r\\n Scope ID: global\\r\\n Version: 1\\r\\n Name: recovery\\r\\n Description: The recovery user is used for any request that was performed with the recovery KMS\\r\\n workflow\\r\\n Autho"] +[10.086736, "o", "rized Actions:\\r\\n no-op\\r\\n read\\r\\n update\\r\\n delete\\r\\n add-accounts\\r\\n set-accounts\\r\\n remove-accounts\\r\\n\\r\\n ID: u_1234567890\\r\\n Scope ID: global\\r\\n Version: 3\\r\\n Name: admin\\r\\n Description: Initial admin user within the \\"global\\" scope\\r\\n Primary Account ID: acctpw_1234567890\\r\\n Login Name: admin\\r\\n Authorized Actions:\\r\\n no-op\\r\\n read\\r\\n update\\r\\n delete\\r\\n add-accounts\\r\\n set-accounts\\r\\n remove-accounts\\r\\n\\r\\n ID: u_0987654321\\r\\n Scope ID: global\\r\\n Version: 3\\r\\n Name: user\\r\\n Description: Initial unprivileged user\\r\\n Primary Account ID: acctpw_0987654321\\r\\n Login Name: user\\r\\n Authorized Actions:\\r\\n no-op\\r\\n read\\r\\n update\\r\\n delete\\r\\n add-accounts\\r\\n set-accounts\\r\\n remove-accounts\\u001b[0m\\r\\n"] +[10.106453, "o", "\\u001b[?2004h\\u001b[1;32m[\\u001b]0;johan@nixos: ~/src/hashicorp/boundary-enterprise\\u0007johan@nixos:~/src/hashicorp/boundary-enterprise]$\\u001b[0m "] +[12.501496, "o", "b"] +[12.703134, "o", "o"] +[12.752198, "o", "u"] +[12.775329, "o", "n"] +[12.905261, "o", "d"] +[13.002373, "o", "a"] +[13.100111, "o", "r"] +[13.354779, "o", "y"] +[13.699827, "o", " "] +[13.998849, "o", "t"] +[14.139192, "o", "a"] +[14.19663, "o", "r"] +[14.392075, "o", "g"] +[14.489938, "o", "e"] +[14.579533, "o", "t"] +[14.674628, "o", "s"] +[14.830951, "o", " "] +[15.015311, "o", "l"] +[15.077147, "o", "i"] +[15.262221, "o", "s"] +[15.355571, "o", "t"] +[15.456597, "o", " "] +[15.91612, "o", "-"] +[16.264491, "o", "r"] +[16.351595, "o", "e"] +[16.798456, "o", "c"] +[16.891689, "o", "u"] +[16.997975, "o", "r"] +[17.176378, "o", "s"] +[17.290104, "o", "i"] +[17.434691, "o", "v"] +[17.482502, "o", "e"] +[18.393541, "o", "\\r\\n"] +[18.39558, "o", "\\u001b[?2004l\\r"] +[18.673452, "o", "\\u001b[0m\\r\\nTarget information:\\r\\n ID: ttcp_1234567890\\r\\n Scope ID: p_1234567890\\r\\n Version: 2\\r\\n Type: tcp\\r\\n Name: Generated target\\r\\n Description: Provides an initial target in Boundary\\r\\n Authorized Actions:\\r\\n no-op\\r\\n read\\r\\n update\\r\\n delete\\r\\n add-host-sources\\r\\n set-host-sources\\r\\n remove-host-sources\\r\\n add-credential-sources\\r\\n set-credential-sources\\r\\n remove-credential-sources\\r\\n authorize-session\\u001b[0m\\r\\n"] +[18.692528, "o", "\\u001b[?2004h\\u001b[1;32m[\\u001b]0;johan@nixos: ~/src/hashicorp/boundary-enterprise\\u0007johan@nixos:~/src/hashicorp/boundary-enterprise]$\\u001b[0m "] +[20.083966, "o", "e"] +[20.37301, "o", "x"] +[20.51445, "o", "i"] +[20.612885, "o", "t"] +[21.303896, "o", "\\r\\n"] +[21.307902, "o", "\\u001b[?2004l\\rexit\\r\\n"]`; + +export const asciiCasts = [asciiCast1, asciiCast2]; diff --git a/addons/api/tests/unit/adapters/session-recording-test.js b/addons/api/tests/unit/adapters/session-recording-test.js new file mode 100644 index 000000000..14696834e --- /dev/null +++ b/addons/api/tests/unit/adapters/session-recording-test.js @@ -0,0 +1,42 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Adapter | session recording', function (hooks) { + setupTest(hooks); + + test('it generates correct URLs for downloading asciicast', function (assert) { + assert.expect(1); + const mockSnapshot = { + adapterOptions: { + method: 'download', + }, + }; + const queryObject = { + mime_type: 'mimeType', + }; + const adapter = this.owner.lookup('adapter:session-recording'); + const createRecordURL = adapter.buildURL( + 'session-recording', + 'sr_id', + mockSnapshot, + 'findRecord', + queryObject + ); + assert.strictEqual( + createRecordURL, + '/v1/session-recordings/sr_id:download?mime_type=mimeType' + ); + }); + + test('it generates correct URLs for retrieving session-recordings', function (assert) { + assert.expect(1); + const adapter = this.owner.lookup('adapter:session-recording'); + const createRecordURL = adapter.buildURL( + 'session-recording', + 'sr_id', + {}, + 'findRecord' + ); + assert.strictEqual(createRecordURL, '/v1/session-recordings/sr_id'); + }); +}); From 48031cca645b2b64904572e322782aa49d90d635 Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Date: Tue, 21 Mar 2023 13:07:39 -0700 Subject: [PATCH 063/193] Add breadcrumbs to session-recording --- .../session-recordings/session-recording.js | 15 +++++++++++++++ .../session-recording/index.hbs | 4 ++++ .../session-recordings/session-recording-test.js | 16 ++++++++++++++++ 3 files changed, 35 insertions(+) create mode 100644 ui/admin/app/controllers/scopes/scope/session-recordings/session-recording.js create mode 100644 ui/admin/tests/unit/controllers/scopes/scope/session-recordings/session-recording-test.js diff --git a/ui/admin/app/controllers/scopes/scope/session-recordings/session-recording.js b/ui/admin/app/controllers/scopes/scope/session-recordings/session-recording.js new file mode 100644 index 000000000..cf762b744 --- /dev/null +++ b/ui/admin/app/controllers/scopes/scope/session-recordings/session-recording.js @@ -0,0 +1,15 @@ +import Controller from '@ember/controller'; +import { inject as service } from '@ember/service'; + +export default class ScopesScopeSessionRecordingsSessionRecordingController extends Controller { + // =services + + @service intl; + + /** + * Session recording breadcrumb + */ + get breadCrumb() { + return this.model.displayName; + } +} diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs index 9641c3084..acd86daed 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs @@ -1,4 +1,8 @@ + + + +

{{t 'resources.session-recording.session.title'}}

diff --git a/ui/admin/tests/unit/controllers/scopes/scope/session-recordings/session-recording-test.js b/ui/admin/tests/unit/controllers/scopes/scope/session-recordings/session-recording-test.js new file mode 100644 index 000000000..9c6be4531 --- /dev/null +++ b/ui/admin/tests/unit/controllers/scopes/scope/session-recordings/session-recording-test.js @@ -0,0 +1,16 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'admin/tests/helpers'; + +module( + 'Unit | Controller | scopes/scope/session-recordings/session-recording', + function (hooks) { + setupTest(hooks); + + test('it exists', function (assert) { + let controller = this.owner.lookup( + 'controller:scopes/scope/session-recordings/session-recording' + ); + assert.ok(controller); + }); + } +); From 2e06d01c3928b68bcbdf101609d5332b8a5f939d Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Date: Tue, 21 Mar 2023 13:20:13 -0700 Subject: [PATCH 064/193] Add breacrumbs for session-recording/channel-by-connection/channel --- .../channels-by-connection/channel.js | 15 +++++++++++++++ .../channels-by-connection/channel.hbs | 4 ++++ .../channels-by-connection/channel-test.js | 16 ++++++++++++++++ 3 files changed, 35 insertions(+) create mode 100644 ui/admin/app/controllers/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.js create mode 100644 ui/admin/tests/unit/controllers/scopes/scope/session-recordings/session-recording/channels-by-connection/channel-test.js diff --git a/ui/admin/app/controllers/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.js b/ui/admin/app/controllers/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.js new file mode 100644 index 000000000..5853cd990 --- /dev/null +++ b/ui/admin/app/controllers/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.js @@ -0,0 +1,15 @@ +import Controller from '@ember/controller'; +import { inject as service } from '@ember/service'; + +export default class ScopesScopeSessionRecordingsSessionRecordingChannelsByConnectionChannelController extends Controller { + // =services + + @service intl; + + /** + * Session recording channel breadcrumb + */ + get breadCrumb() { + return this.model.channel_id; + } +} diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs index f36440b2a..57ede0481 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs @@ -1,6 +1,10 @@ {{page-title (t 'resources.session-recording.channel.title')}} + + + +

{{t 'resources.session-recording.channel.title'}}

diff --git a/ui/admin/tests/unit/controllers/scopes/scope/session-recordings/session-recording/channels-by-connection/channel-test.js b/ui/admin/tests/unit/controllers/scopes/scope/session-recordings/session-recording/channels-by-connection/channel-test.js new file mode 100644 index 000000000..0c68630bc --- /dev/null +++ b/ui/admin/tests/unit/controllers/scopes/scope/session-recordings/session-recording/channels-by-connection/channel-test.js @@ -0,0 +1,16 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'admin/tests/helpers'; + +module( + 'Unit | Controller | scopes/scope/session-recordings/session-recording/channels-by-connection/channel', + function (hooks) { + setupTest(hooks); + + test('it exists', function (assert) { + let controller = this.owner.lookup( + 'controller:scopes/scope/session-recordings/session-recording/channels-by-connection/channel' + ); + assert.ok(controller); + }); + } +); From db2d26df9a711eccbf279eee395e870d578ffb77 Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Date: Tue, 21 Mar 2023 17:35:43 -0700 Subject: [PATCH 065/193] Add acceptance test for session-recordings/session-recording controller --- .../session-recordings/list-test.js | 2 + .../session-recording-test.js | 48 +++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 ui/admin/tests/acceptance/session-recordings/session-recording/session-recording-test.js diff --git a/ui/admin/tests/acceptance/session-recordings/list-test.js b/ui/admin/tests/acceptance/session-recordings/list-test.js index ebeca115a..8a868b266 100644 --- a/ui/admin/tests/acceptance/session-recordings/list-test.js +++ b/ui/admin/tests/acceptance/session-recordings/list-test.js @@ -12,6 +12,7 @@ module('Acceptance | session recordings | list', function (hooks) { const LIST_SESSION_RECORDING_BUTTON = 'table > tbody > tr > td:last-child > a'; + // Instances const instances = { scopes: { global: null, @@ -20,6 +21,7 @@ module('Acceptance | session recordings | list', function (hooks) { sessionRecording: null, }; + // Urls const urls = { globalScope: null, sessionRecordings: null, diff --git a/ui/admin/tests/acceptance/session-recordings/session-recording/session-recording-test.js b/ui/admin/tests/acceptance/session-recordings/session-recording/session-recording-test.js new file mode 100644 index 000000000..5177f2a56 --- /dev/null +++ b/ui/admin/tests/acceptance/session-recordings/session-recording/session-recording-test.js @@ -0,0 +1,48 @@ +import { module, test } from 'qunit'; +import { visit, currentURL } from '@ember/test-helpers'; +import { setupApplicationTest } from 'admin/tests/helpers'; +import setupMirage from 'ember-cli-mirage/test-support/setup-mirage'; +import { authenticateSession } from 'ember-simple-auth/test-support'; + +module('Acceptance | session recordings | session recording', function (hooks) { + setupApplicationTest(hooks); + setupMirage(hooks); + + // Instances + const instances = { + scopes: { + global: null, + org: null, + }, + sessionRecording: null, + }; + // Urls + const urls = { + globalScope: null, + sessionRecordings: null, + sessionRecording: null, + }; + + hooks.beforeEach(function () { + instances.scopes.global = this.server.create('scope', { id: 'global' }); + instances.scopes.org = this.server.create('scope', { + type: 'org', + scope: { id: 'global', type: 'global' }, + }); + instances.sessionRecording = this.server.create('session-recording', { + scope: instances.scopes.global, + }); + urls.globalScope = `/scopes/global`; + urls.sessionRecordings = `${urls.globalScope}/session-recordings`; + urls.sessionRecording = `${urls.sessionRecordings}/${instances.sessionRecording.id}`; + authenticateSession({}); + }); + + test('user can navigate to a session recording', async function (assert) { + assert.expect(1); + + // Visit session recording + await visit(urls.sessionRecording); + assert.strictEqual(currentURL(), urls.sessionRecording); + }); +}); From b33efbd5c35f189808a892261629a5872b6bf67d Mon Sep 17 00:00:00 2001 From: dharini Date: Wed, 22 Mar 2023 16:34:31 +0530 Subject: [PATCH 066/193] =?UTF-8?q?chore:=20=F0=9F=A4=96=20style=20updates?= =?UTF-8?q?,=20incl=20var=20arg=20to=20make=20it=20read-write?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../form/field/secret-input/index.hbs | 8 ++- .../form/field/secret-input/index.js | 3 +- .../components/form/storage-bucket/index.hbs | 55 ++++++++++++++++++- .../components/form/storage-bucket/index.js | 9 +++ .../components/form/target/details/index.hbs | 50 ++++++++--------- ui/admin/app/styles/app.scss | 20 +++---- 6 files changed, 103 insertions(+), 42 deletions(-) diff --git a/ui/admin/app/components/form/field/secret-input/index.hbs b/ui/admin/app/components/form/field/secret-input/index.hbs index 95b7235e8..0b7f56a33 100644 --- a/ui/admin/app/components/form/field/secret-input/index.hbs +++ b/ui/admin/app/components/form/field/secret-input/index.hbs @@ -4,14 +4,16 @@ }}
+ {{#if (or this.isDisabled this.isActionable)}} + + {{/if}} diff --git a/ui/admin/app/components/form/field/secret-input/index.js b/ui/admin/app/components/form/field/secret-input/index.js index 3a1876f7a..d1d1fdb51 100644 --- a/ui/admin/app/components/form/field/secret-input/index.js +++ b/ui/admin/app/components/form/field/secret-input/index.js @@ -14,7 +14,6 @@ export default class FormFieldSecretInputIndexComponent extends Component { * @type {boolean} */ @tracked editing = false; - @tracked secret; /** * Returns true if the resource form is in read only mode @@ -52,7 +51,7 @@ export default class FormFieldSecretInputIndexComponent extends Component { */ @action cancelEdit() { - this.secret = null; this.editing = false; + this.args.cancel(); } } diff --git a/ui/admin/app/components/form/storage-bucket/index.hbs b/ui/admin/app/components/form/storage-bucket/index.hbs index 5c92f882b..47e075b61 100644 --- a/ui/admin/app/components/form/storage-bucket/index.hbs +++ b/ui/admin/app/components/form/storage-bucket/index.hbs @@ -5,7 +5,7 @@ + {{#if @model.isNew}} + + {{t + 'resources.storage-bucket.form.access_key_id.label' + }} + {{t + 'resources.storage-bucket.form.access_key_id.help' + }} + {{#if @model.errors.access_key_id}} + + {{#each @model.errors.access_key_id as |error|}} + {{error.message}} + {{/each}} + + {{/if}} + + {{else}} + + {{t + 'resources.storage-bucket.form.access_key_id.label' + }} + {{t + 'resources.storage-bucket.form.access_key_id.help' + }} + {{#if @model.errors.access_key_id}} + + {{#each @model.errors.access_key_id as |error|}} + {{error.message}} + {{/each}} + + {{/if}} + + {{/if}} {{#if @model.isNew}} {{/if}} - + + {{t 'resources.storage-bucket.form.access_key_id.label'}} + {{t + 'resources.storage-bucket.form.access_key_id.help' + }} + {{#if @model.errors.access_key_id}} + + {{#each @model.errors.access_key_id as |error|}} + {{error.message}} + {{/each}} + + {{/if}} + {{#if (and @model.isNew (feature-flag 'ssh-target'))}} {{t 'resources.target.form.type.label'}} @@ -84,31 +107,6 @@ {{/if}} - {{#if (feature-flag 'target-network-address')}} - - {{t 'resources.target.form.target-address.label'}} - {{t - 'resources.target.form.target-address.help' - }} - {{#if @model.errors.address}} - - {{#each @model.errors.address as |error|}} - {{error.message}} - {{/each}} - - {{/if}} - - {{/if}} - Date: Wed, 22 Mar 2023 16:42:58 +0530 Subject: [PATCH 067/193] =?UTF-8?q?fix:=20=F0=9F=90=9B=20undo=20change?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/form/storage-bucket/index.hbs | 53 ------------------- .../components/form/storage-bucket/index.js | 1 - .../components/form/target/details/index.hbs | 50 ++++++++--------- 3 files changed, 26 insertions(+), 78 deletions(-) diff --git a/ui/admin/app/components/form/storage-bucket/index.hbs b/ui/admin/app/components/form/storage-bucket/index.hbs index 47e075b61..7a44ba0c4 100644 --- a/ui/admin/app/components/form/storage-bucket/index.hbs +++ b/ui/admin/app/components/form/storage-bucket/index.hbs @@ -217,60 +217,7 @@ {{/if}} {{/if}} - {{#if @model.isNew}} - - {{t - 'resources.storage-bucket.form.access_key_id.label' - }} - {{t - 'resources.storage-bucket.form.access_key_id.help' - }} - {{#if @model.errors.access_key_id}} - - {{#each @model.errors.access_key_id as |error|}} - {{error.message}} - {{/each}} - - {{/if}} - - {{else}} - - {{t - 'resources.storage-bucket.form.access_key_id.label' - }} - {{t - 'resources.storage-bucket.form.access_key_id.help' - }} - {{#if @model.errors.access_key_id}} - - {{#each @model.errors.access_key_id as |error|}} - {{error.message}} - {{/each}} - - {{/if}} - - - {{/if}} {{/if}} - - {{t 'resources.storage-bucket.form.access_key_id.label'}} - {{t - 'resources.storage-bucket.form.access_key_id.help' - }} - {{#if @model.errors.access_key_id}} - - {{#each @model.errors.access_key_id as |error|}} - {{error.message}} - {{/each}} - - {{/if}} - + {{#if (and @model.isNew (feature-flag 'ssh-target'))}} {{t 'resources.target.form.type.label'}} @@ -107,6 +84,31 @@ {{/if}} + {{#if (feature-flag 'target-network-address')}} + + {{t 'resources.target.form.target-address.label'}} + {{t + 'resources.target.form.target-address.help' + }} + {{#if @model.errors.address}} + + {{#each @model.errors.address as |error|}} + {{error.message}} + {{/each}} + + {{/if}} + + {{/if}} + Date: Wed, 22 Mar 2023 16:52:58 +0530 Subject: [PATCH 068/193] =?UTF-8?q?chore:=20=F0=9F=A4=96=20move=20componen?= =?UTF-8?q?t=20invocation=20to=20a=20separate=20PR?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/form/storage-bucket/index.hbs | 77 ++++++------------- .../components/form/storage-bucket/index.js | 8 -- 2 files changed, 23 insertions(+), 62 deletions(-) diff --git a/ui/admin/app/components/form/storage-bucket/index.hbs b/ui/admin/app/components/form/storage-bucket/index.hbs index 7a44ba0c4..2413fd29f 100644 --- a/ui/admin/app/components/form/storage-bucket/index.hbs +++ b/ui/admin/app/components/form/storage-bucket/index.hbs @@ -5,7 +5,7 @@ - {{#if @model.isNew}} - - {{t - 'resources.storage-bucket.form.access_key_id.label' - }} - {{t - 'resources.storage-bucket.form.access_key_id.help' - }} - {{#if @model.errors.access_key_id}} - - {{#each @model.errors.access_key_id as |error|}} - {{error.message}} - {{/each}} - - {{/if}} - - {{else}} - - {{t - 'resources.storage-bucket.form.access_key_id.label' - }} - {{t - 'resources.storage-bucket.form.access_key_id.help' - }} - {{#if @model.errors.access_key_id}} - - {{#each @model.errors.access_key_id as |error|}} - {{error.message}} - {{/each}} - - {{/if}} - - {{/if}} + + {{t 'resources.storage-bucket.form.access_key_id.label'}} + {{t + 'resources.storage-bucket.form.access_key_id.help' + }} + {{#if @model.errors.access_key_id}} + + {{#each @model.errors.access_key_id as |error|}} + {{error.message}} + {{/each}} + + {{/if}} + Date: Wed, 22 Mar 2023 10:52:33 -0400 Subject: [PATCH 069/193] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20Add=20new=20targ?= =?UTF-8?q?et=20field=20for=20storage=20bucket=20(#133)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit βœ… Closes: ICU-8077 --- addons/api/addon/generated/models/target.js | 5 ++ addons/api/addon/models/target.js | 39 +++++++++ addons/api/addon/serializers/target.js | 23 ++++++ addons/api/tests/unit/models/target-test.js | 67 ++++++++++++++++ .../api/tests/unit/serializers/target-test.js | 80 +++++++++++++++++++ 5 files changed, 214 insertions(+) diff --git a/addons/api/addon/generated/models/target.js b/addons/api/addon/generated/models/target.js index 2c7e3ae14..0cc726387 100644 --- a/addons/api/addon/generated/models/target.js +++ b/addons/api/addon/generated/models/target.js @@ -83,4 +83,9 @@ export default class GeneratedTargetModel extends BaseModel { 'An IP address or DNS name for the session to connect to. Cannot be used in conjunction with host sources.', }) address; + + @attr('string', { + description: 'The storage bucket associated with this target.', + }) + storage_bucket_id; } diff --git a/addons/api/addon/models/target.js b/addons/api/addon/models/target.js index 79a784e5e..bea1c006b 100644 --- a/addons/api/addon/models/target.js +++ b/addons/api/addon/models/target.js @@ -323,6 +323,45 @@ export default class TargetModel extends GeneratedTargetModel { options ); } + + /** + * @param {object} options + * @param {object} options.adapterOptions + * @returns {Promise} + */ + setStorageBucket(options = { adapterOptions: {} }) { + const defaultAdapterOptions = { + method: 'set-storage-bucket', + }; + + return this.save({ + ...options, + adapterOptions: { + ...defaultAdapterOptions, + ...options.adapterOptions, + }, + }); + } + + /** + * @param {object} options + * @param {object} options.adapterOptions + * @returns {Promise} + */ + removeStorageBucket(options = { adapterOptions: {} }) { + const defaultAdapterOptions = { + method: 'remove-storage-bucket', + }; + + return this.save({ + ...options, + adapterOptions: { + ...defaultAdapterOptions, + ...options.adapterOptions, + }, + }); + } + /** * True if the target type is tcp. * @type {boolean} diff --git a/addons/api/addon/serializers/target.js b/addons/api/addon/serializers/target.js index d79cb3799..25a952cfc 100644 --- a/addons/api/addon/serializers/target.js +++ b/addons/api/addon/serializers/target.js @@ -41,6 +41,16 @@ export default class TargetSerializer extends ApplicationSerializer { snapshot, injectedApplicationCredentialSourceIDs ); + + if (snapshot?.adapterOptions?.method === 'set-storage-bucket') { + serialized = this.serializeWithStorageBucket(snapshot); + } + if (snapshot?.adapterOptions?.method === 'remove-storage-bucket') { + return { + version: snapshot.attr('version'), + }; + } + return serialized; } @@ -91,4 +101,17 @@ export default class TargetSerializer extends ApplicationSerializer { injected_application_credential_source_ids, }; } + + /** + * Returns a payload containing only version and storage bucket id, + * rather than existing instances on the model. + * @param {Snapshot} snapshot + * @returns {object} + */ + serializeWithStorageBucket(snapshot) { + return { + version: snapshot.attr('version'), + storage_bucket_id: snapshot?.attr('storage_bucket_id'), + }; + } } diff --git a/addons/api/tests/unit/models/target-test.js b/addons/api/tests/unit/models/target-test.js index 32555baa3..680ae429f 100644 --- a/addons/api/tests/unit/models/target-test.js +++ b/addons/api/tests/unit/models/target-test.js @@ -404,4 +404,71 @@ module('Unit | Model | target', function (hooks) { assert.true(modelTCP.isTCP); assert.false(modelTCP.isSSH); }); + + test('it has a `setStorageBucket` method that targets a specific POST API endpoint and serialization', async function (assert) { + assert.expect(1); + this.server.post( + '/v1/targets/123abc:set-storage-bucket', + (schema, request) => { + const body = JSON.parse(request.requestBody); + assert.deepEqual(body, { + storage_bucket_id: 'bucketID', + version: 1, + }); + return { id: '123abc' }; + } + ); + const store = this.owner.lookup('service:store'); + store.push({ + data: { + id: '123abc', + type: 'target', + attributes: { + name: 'Target', + description: 'Description', + storage_bucket_id: 'bucketID', + version: 1, + scope: { + scope_id: 'o_1', + type: 'scope', + }, + }, + }, + }); + const model = store.peekRecord('target', '123abc'); + await model.setStorageBucket(); + }); + + test('it has a `removeStorageBucket` method that targets a specific POST API endpoint and serialization', async function (assert) { + assert.expect(1); + this.server.post( + '/v1/targets/123abc:remove-storage-bucket', + (schema, request) => { + const body = JSON.parse(request.requestBody); + assert.deepEqual(body, { + version: 1, + }); + return { id: '123abc' }; + } + ); + const store = this.owner.lookup('service:store'); + store.push({ + data: { + id: '123abc', + type: 'target', + attributes: { + name: 'Target', + description: 'Description', + storage_bucket_id: null, + version: 1, + scope: { + scope_id: 'o_1', + type: 'scope', + }, + }, + }, + }); + const model = store.peekRecord('target', '123abc'); + await model.removeStorageBucket(); + }); }); diff --git a/addons/api/tests/unit/serializers/target-test.js b/addons/api/tests/unit/serializers/target-test.js index c531a311a..f81809c66 100644 --- a/addons/api/tests/unit/serializers/target-test.js +++ b/addons/api/tests/unit/serializers/target-test.js @@ -49,6 +49,7 @@ module('Unit | Serializer | target', function (hooks) { worker_filter: null, egress_worker_filter: null, ingress_worker_filter: null, + storage_bucket_id: null, attributes: { default_port: 1234, }, @@ -127,6 +128,49 @@ module('Unit | Serializer | target', function (hooks) { }); }); + test('it serializes only storage_bucket_id and version when an `adapterOptions.method` is passed for set storage bucket', function (assert) { + assert.expect(1); + const store = this.owner.lookup('service:store'); + const serializer = store.serializerFor('target'); + const record = store.createRecord('target', { + name: 'User', + description: 'Description', + storage_bucket_id: 'bucketID', + version: 1, + }); + const snapshot = record._createSnapshot(); + snapshot.adapterOptions = { + method: 'set-storage-bucket', + }; + const serializedRecord = serializer.serialize(snapshot); + + assert.deepEqual(serializedRecord, { + storage_bucket_id: 'bucketID', + version: 1, + }); + }); + + test('it serializes only version when an `adapterOptions.method` is passed for remove storage bucket', function (assert) { + assert.expect(1); + const store = this.owner.lookup('service:store'); + const serializer = store.serializerFor('target'); + const record = store.createRecord('target', { + name: 'User', + description: 'Description', + storage_bucket_id: 'bucketID', + version: 1, + }); + const snapshot = record._createSnapshot(); + snapshot.adapterOptions = { + method: 'remove-storage-bucket', + }; + const serializedRecord = serializer.serialize(snapshot); + + assert.deepEqual(serializedRecord, { + version: 1, + }); + }); + test('it serializes the worker_filter attribute if present', function (assert) { assert.expect(1); const store = this.owner.lookup('service:store'); @@ -155,6 +199,7 @@ module('Unit | Serializer | target', function (hooks) { worker_filter: 'worker', egress_worker_filter: null, ingress_worker_filter: null, + storage_bucket_id: null, attributes: { default_port: 1234, }, @@ -190,6 +235,7 @@ module('Unit | Serializer | target', function (hooks) { worker_filter: null, egress_worker_filter: 'egress worker', ingress_worker_filter: null, + storage_bucket_id: null, attributes: { default_port: 1234, }, @@ -225,6 +271,7 @@ module('Unit | Serializer | target', function (hooks) { worker_filter: null, egress_worker_filter: null, ingress_worker_filter: 'ingress worker', + storage_bucket_id: null, attributes: { default_port: 1234, }, @@ -438,4 +485,37 @@ module('Unit | Serializer | target', function (hooks) { }, }); }); + + test('it normalizes the storage_bucket_id attribute if present', function (assert) { + assert.expect(1); + const store = this.owner.lookup('service:store'); + const serializer = store.serializerFor('target'); + const target = store.createRecord('target').constructor; + const payload = { + id: '1', + name: 'Target 1', + storage_bucket_id: 'bucketID', + }; + const normalized = serializer.normalizeSingleResponse( + store, + target, + payload + ); + assert.deepEqual(normalized, { + included: [], + data: { + id: '1', + type: 'target', + attributes: { + authorized_actions: [], + name: 'Target 1', + host_sources: [], + brokered_credential_source_ids: [], + injected_application_credential_source_ids: [], + storage_bucket_id: 'bucketID', + }, + relationships: {}, + }, + }); + }); }); From 9bf03b0fba17b461f395a560c5ce6443865da567 Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Date: Wed, 22 Mar 2023 08:15:59 -0700 Subject: [PATCH 070/193] Add acceptance test for session-recordings/session-recording/channels-by-connection/channel --- .../channels-by-connection/channel-test.js | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 ui/admin/tests/acceptance/session-recordings/session-recording/channels-by-connection/channel-test.js diff --git a/ui/admin/tests/acceptance/session-recordings/session-recording/channels-by-connection/channel-test.js b/ui/admin/tests/acceptance/session-recordings/session-recording/channels-by-connection/channel-test.js new file mode 100644 index 000000000..a971cdb27 --- /dev/null +++ b/ui/admin/tests/acceptance/session-recordings/session-recording/channels-by-connection/channel-test.js @@ -0,0 +1,63 @@ +import { module, test } from 'qunit'; +import { visit, currentURL } from '@ember/test-helpers'; +import { setupApplicationTest } from 'admin/tests/helpers'; +import setupMirage from 'ember-cli-mirage/test-support/setup-mirage'; +import { authenticateSession } from 'ember-simple-auth/test-support'; + +module( + 'Acceptance | session recordings | session recording | channels by connection | channel', + function (hooks) { + setupApplicationTest(hooks); + setupMirage(hooks); + + // Instances + const instances = { + scopes: { + global: null, + org: null, + }, + sessionRecording: null, + connectionRecording: null, + channelRecording: null, + }; + + // Urls + const urls = { + globalScope: null, + sessionRecordings: null, + sessionRecording: null, + }; + + hooks.beforeEach(function () { + instances.scopes.global = this.server.create('scope', { id: 'global' }); + instances.scopes.org = this.server.create('scope', { + type: 'org', + scope: { id: 'global', type: 'global' }, + }); + instances.sessionRecording = this.server.create('session-recording', { + scope: instances.scopes.global, + }); + instances.connectionRecording = this.server.create( + 'connection-recording', + { + session_recording: instances.sessionRecording, + } + ); + instances.channelRecording = this.server.create('channel-recording', { + connection_recording: instances.connectionRecording, + }); + urls.globalScope = `/scopes/global`; + urls.sessionRecordings = `${urls.globalScope}/session-recordings`; + urls.sessionRecording = `${urls.sessionRecordings}/${instances.sessionRecording.id}`; + urls.connectionRecording = `${urls.sessionRecording}/channels-by-connection/${instances.channelRecording.id}`; + authenticateSession({}); + }); + + test('user can navigate to a channel', async function (assert) { + assert.expect(1); + // Visit channel + await visit(urls.connectionRecording); + assert.strictEqual(currentURL(), urls.connectionRecording); + }); + } +); From c144275358b11362278329322ccc3443d9d8cfcb Mon Sep 17 00:00:00 2001 From: lisbet-alvarez <107949262+lisbet-alvarez@users.noreply.github.com> Date: Wed, 22 Mar 2023 14:48:44 -0700 Subject: [PATCH 071/193] =?UTF-8?q?chore:=20=F0=9F=A4=96=20add=20new=20rou?= =?UTF-8?q?te=20enable=20session=20recording=20(#140)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit βœ… Closes: ICU-8542 --- addons/core/translations/resources/en-us.yaml | 1 + ui/admin/app/router.js | 1 + .../targets/target/enable-session-recording.js | 3 +++ .../targets/target/enable-session-recording.hbs | 2 ++ .../target/enable-session-recording-test.js | 16 ++++++++++++++++ 5 files changed, 23 insertions(+) create mode 100644 ui/admin/app/routes/scopes/scope/targets/target/enable-session-recording.js create mode 100644 ui/admin/app/templates/scopes/scope/targets/target/enable-session-recording.hbs create mode 100644 ui/admin/tests/unit/routes/scopes/scope/targets/target/enable-session-recording-test.js diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml index 1deee0f25..26f3bfca5 100644 --- a/addons/core/translations/resources/en-us.yaml +++ b/addons/core/translations/resources/en-us.yaml @@ -368,6 +368,7 @@ target: add-brokered-credential-sources: Add Brokered Credentials add-injected-application-credential-sources: Add Injected Application Credentials remove-address: Remove address and save + enable-session-recording: Enable Session Recording types: tcp: Generic TCP ssh: SSH diff --git a/ui/admin/app/router.js b/ui/admin/app/router.js index 0187e2f03..8b36ebc98 100644 --- a/ui/admin/app/router.js +++ b/ui/admin/app/router.js @@ -85,6 +85,7 @@ Router.map(function () { this.route('injected-application-credential-sources'); this.route('add-brokered-credential-sources'); this.route('add-injected-application-credential-sources'); + this.route('enable-session-recording'); }); this.route('new'); }); diff --git a/ui/admin/app/routes/scopes/scope/targets/target/enable-session-recording.js b/ui/admin/app/routes/scopes/scope/targets/target/enable-session-recording.js new file mode 100644 index 000000000..d6dd6e257 --- /dev/null +++ b/ui/admin/app/routes/scopes/scope/targets/target/enable-session-recording.js @@ -0,0 +1,3 @@ +import Route from '@ember/routing/route'; + +export default class ScopesScopeTargetsTargetEnableSessionRecordingRoute extends Route {} diff --git a/ui/admin/app/templates/scopes/scope/targets/target/enable-session-recording.hbs b/ui/admin/app/templates/scopes/scope/targets/target/enable-session-recording.hbs new file mode 100644 index 000000000..559ab26d4 --- /dev/null +++ b/ui/admin/app/templates/scopes/scope/targets/target/enable-session-recording.hbs @@ -0,0 +1,2 @@ +{{page-title (t 'resources.target.actions.enable-session-recording')}} +{{outlet}} \ No newline at end of file diff --git a/ui/admin/tests/unit/routes/scopes/scope/targets/target/enable-session-recording-test.js b/ui/admin/tests/unit/routes/scopes/scope/targets/target/enable-session-recording-test.js new file mode 100644 index 000000000..434a711fa --- /dev/null +++ b/ui/admin/tests/unit/routes/scopes/scope/targets/target/enable-session-recording-test.js @@ -0,0 +1,16 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'admin/tests/helpers'; + +module( + 'Unit | Route | scopes/scope/targets/target/enable-session-recording', + function (hooks) { + setupTest(hooks); + + test('it exists', function (assert) { + let route = this.owner.lookup( + 'route:scopes/scope/targets/target/enable-session-recording' + ); + assert.ok(route); + }); + } +); From 84de198359faac6fab289862e16de32a1a227f76 Mon Sep 17 00:00:00 2001 From: Cameron Perera Date: Wed, 22 Mar 2023 17:07:46 -0500 Subject: [PATCH 072/193] =?UTF-8?q?refactor:=20=F0=9F=92=A1=20update=20pla?= =?UTF-8?q?yer=20header=20styles=20(#136)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ui/admin/app/styles/app.scss | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/ui/admin/app/styles/app.scss b/ui/admin/app/styles/app.scss index cf263297c..6233388e3 100644 --- a/ui/admin/app/styles/app.scss +++ b/ui/admin/app/styles/app.scss @@ -697,19 +697,13 @@ border-radius: 0.75rem; &-header { - padding-left: 1rem; - height: 3rem; - width: 100%; border-bottom: var(--player-divider) 0.125rem solid; // override of standalone link styles to allow for // static colors in light and dark mode - .hds-link-standalone { - height: inherit; - } - a { color: var(--link-color); + padding: 1rem; } a:hover { From ca5b9f1d2457c9a788f0fa9d843bc9d2d7390eb7 Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Date: Wed, 22 Mar 2023 15:25:46 -0700 Subject: [PATCH 073/193] Add channels-by-connection to the breadcrumbs --- addons/core/translations/resources/en-us.yaml | 2 ++ .../channels-by-connection.js | 18 ++++++++++++++++++ .../scopes/scope/session-recordings-test.js | 2 +- .../session-recording-test.js | 2 +- .../channels-by-connection-test.js | 16 ++++++++++++++++ .../channels-by-connection/channel-test.js | 2 +- 6 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 ui/admin/app/controllers/scopes/scope/session-recordings/session-recording/channels-by-connection.js create mode 100644 ui/admin/tests/unit/controllers/scopes/scope/session-recordings/session-recording/channels-by-connection-test.js diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml index 1deee0f25..6eab387ea 100644 --- a/addons/core/translations/resources/en-us.yaml +++ b/addons/core/translations/resources/en-us.yaml @@ -217,6 +217,8 @@ session-recording: connection: title: Connection title_plural: Connections + channels-by-connection: + title: Channels by connection channel: title: Channel title_plural: Channels diff --git a/ui/admin/app/controllers/scopes/scope/session-recordings/session-recording/channels-by-connection.js b/ui/admin/app/controllers/scopes/scope/session-recordings/session-recording/channels-by-connection.js new file mode 100644 index 000000000..a16cea405 --- /dev/null +++ b/ui/admin/app/controllers/scopes/scope/session-recordings/session-recording/channels-by-connection.js @@ -0,0 +1,18 @@ +import Controller from '@ember/controller'; +import { inject as service } from '@ember/service'; + +export default class ScopesScopeSessionRecordingsSessionRecordingChannelsByConnectionController extends Controller { + // =services + + @service intl; + + // =attributes + /** + * Translated breadcrumb + */ + get breadCrumb() { + return this.intl.t( + 'resources.session-recording.channels-by-connection.title' + ); + } +} diff --git a/ui/admin/tests/unit/controllers/scopes/scope/session-recordings-test.js b/ui/admin/tests/unit/controllers/scopes/scope/session-recordings-test.js index 94159166b..99bb09ace 100644 --- a/ui/admin/tests/unit/controllers/scopes/scope/session-recordings-test.js +++ b/ui/admin/tests/unit/controllers/scopes/scope/session-recordings-test.js @@ -1,7 +1,7 @@ import { module, test } from 'qunit'; import { setupTest } from 'admin/tests/helpers'; -module('Unit | Controller | scopes/scope/session-recordings', function (hooks) { +module('Unit | Controller | session-recordings', function (hooks) { setupTest(hooks); test('it exists', function (assert) { diff --git a/ui/admin/tests/unit/controllers/scopes/scope/session-recordings/session-recording-test.js b/ui/admin/tests/unit/controllers/scopes/scope/session-recordings/session-recording-test.js index 9c6be4531..842723c89 100644 --- a/ui/admin/tests/unit/controllers/scopes/scope/session-recordings/session-recording-test.js +++ b/ui/admin/tests/unit/controllers/scopes/scope/session-recordings/session-recording-test.js @@ -2,7 +2,7 @@ import { module, test } from 'qunit'; import { setupTest } from 'admin/tests/helpers'; module( - 'Unit | Controller | scopes/scope/session-recordings/session-recording', + 'Unit | Controller | session-recordings | session-recording', function (hooks) { setupTest(hooks); diff --git a/ui/admin/tests/unit/controllers/scopes/scope/session-recordings/session-recording/channels-by-connection-test.js b/ui/admin/tests/unit/controllers/scopes/scope/session-recordings/session-recording/channels-by-connection-test.js new file mode 100644 index 000000000..4e0d89aaa --- /dev/null +++ b/ui/admin/tests/unit/controllers/scopes/scope/session-recordings/session-recording/channels-by-connection-test.js @@ -0,0 +1,16 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'admin/tests/helpers'; + +module( + 'Unit | Controller | session-recordings | session-recording | channels-by-connection', + function (hooks) { + setupTest(hooks); + + test('it exists', function (assert) { + let controller = this.owner.lookup( + 'controller:scopes/scope/session-recordings/session-recording/channels-by-connection' + ); + assert.ok(controller); + }); + } +); diff --git a/ui/admin/tests/unit/controllers/scopes/scope/session-recordings/session-recording/channels-by-connection/channel-test.js b/ui/admin/tests/unit/controllers/scopes/scope/session-recordings/session-recording/channels-by-connection/channel-test.js index 0c68630bc..4841bc908 100644 --- a/ui/admin/tests/unit/controllers/scopes/scope/session-recordings/session-recording/channels-by-connection/channel-test.js +++ b/ui/admin/tests/unit/controllers/scopes/scope/session-recordings/session-recording/channels-by-connection/channel-test.js @@ -2,7 +2,7 @@ import { module, test } from 'qunit'; import { setupTest } from 'admin/tests/helpers'; module( - 'Unit | Controller | scopes/scope/session-recordings/session-recording/channels-by-connection/channel', + 'Unit | Controller | session-recordings | session-recording | channels-by-connection | channel', function (hooks) { setupTest(hooks); From b8c38dd0b3314672eceea5af813c9f78810f08a3 Mon Sep 17 00:00:00 2001 From: dharini Date: Thu, 23 Mar 2023 10:28:16 +0530 Subject: [PATCH 074/193] =?UTF-8?q?chore:=20=F0=9F=A4=96=20var=20names?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/components/form/field/secret-input/index.hbs | 4 ++-- .../app/components/form/field/secret-input/index.js | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/ui/admin/app/components/form/field/secret-input/index.hbs b/ui/admin/app/components/form/field/secret-input/index.hbs index 0b7f56a33..721ef39dd 100644 --- a/ui/admin/app/components/form/field/secret-input/index.hbs +++ b/ui/admin/app/components/form/field/secret-input/index.hbs @@ -13,7 +13,7 @@ @value={{@value}} @type={{@type}} name={{@name}} - disabled={{or @disabled (not this.editing)}} + disabled={{or @isDisabled (not this.isEditing)}} ...attributes as |F| > @@ -24,7 +24,7 @@ {{else if this.isActionable}} Date: Thu, 23 Mar 2023 10:45:28 +0530 Subject: [PATCH 075/193] =?UTF-8?q?fix:=20=F0=9F=90=9B=20translation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- addons/core/translations/resources/en-us.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml index 89a58b976..beab91ebe 100644 --- a/addons/core/translations/resources/en-us.yaml +++ b/addons/core/translations/resources/en-us.yaml @@ -255,7 +255,7 @@ storage-bucket: help: The AWS region to use access_key_id: label: Access key ID - help: The Access key ID generated by AWS for the IAM User to use with this host catalog. We will not show this data after it is saved, but you can replace. + help: The Access key ID generated by AWS for the IAM User to use with this storage bucket. We will not show this data after it is saved, but you can replace. secret_access_key: label: Secret access key help: The secret access key to use. From b74c4ae03d5227cd662f16e237a8739a1e39b1dc Mon Sep 17 00:00:00 2001 From: dharini Date: Thu, 23 Mar 2023 11:44:57 +0530 Subject: [PATCH 076/193] =?UTF-8?q?chore:=20=F0=9F=A4=96=20add=20session-r?= =?UTF-8?q?ecording=20flag=20to=20updated=20configs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ui/admin/config/features.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ui/admin/config/features.js b/ui/admin/config/features.js index cad1ab6d0..5af97dfff 100644 --- a/ui/admin/config/features.js +++ b/ui/admin/config/features.js @@ -14,6 +14,7 @@ const baseEdition = { 'target-worker-filters-v2-hcp': false, 'target-network-address': false, 'vault-worker-filter': false, + 'session-recording': false, }; // Editions maps edition keys to their associated featuresets. const featureEditions = {}; @@ -30,6 +31,7 @@ featureEditions.enterprise = { 'ssh-target': true, 'target-worker-filters-v2-ingress': true, 'vault-worker-filter': true, + 'session-recording': true, }; featureEditions.hcp = { ...featureEditions.enterprise, From 456a5944e0fe4becc22c273439367534fef99710 Mon Sep 17 00:00:00 2001 From: Zhihe Li Date: Thu, 23 Mar 2023 12:09:39 -0400 Subject: [PATCH 077/193] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20Add=20mirage=20d?= =?UTF-8?q?ata=20for=20storage=20bucket=20id=20on=20targets=20(#141)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit βœ… Closes: ICU-8080 --- addons/api/mirage/factories/target.js | 10 ++++++++++ addons/api/mirage/route-handlers/target.js | 9 +++++++++ addons/api/mirage/scenarios/default.js | 8 +++++--- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/addons/api/mirage/factories/target.js b/addons/api/mirage/factories/target.js index e664a1532..8a4a93cc6 100644 --- a/addons/api/mirage/factories/target.js +++ b/addons/api/mirage/factories/target.js @@ -26,6 +26,8 @@ export default factory.extend({ 'remove-host-sources', 'add-credential-sources', 'remove-credential-sources', + 'set-storage-bucket', + 'remove-storage-bucket', ], id: () => generateId('t_'), @@ -66,6 +68,14 @@ export default factory.extend({ .where((credential) => credential.scopeId === target.scope.id) .models.filter(() => randomBoolean()) .map((cred) => cred.id); + + const randomlySelectedStorageBucket = faker.helpers.arrayElement( + server.schema.storageBuckets.all().models + ); + if (randomlySelectedStorageBucket && randomBoolean()) { + target.update({ storage_bucket_id: randomlySelectedStorageBucket.id }); + } + target.update({ hostSets: randomlySelectedHostSets, brokeredCredentialSourceIds: [ diff --git a/addons/api/mirage/route-handlers/target.js b/addons/api/mirage/route-handlers/target.js index b26c59b7e..5d7897ee2 100644 --- a/addons/api/mirage/route-handlers/target.js +++ b/addons/api/mirage/route-handlers/target.js @@ -100,5 +100,14 @@ export function targetHandler({ targets }, { params: { idMethod } }) { removedCredentialSources; } } + + if (method === 'add-storage-bucket') { + updatedAttrs.storage_bucket_id = attrs.storage_bucket_id; + } + + if (method === 'remove-storage-bucket') { + updatedAttrs.storage_bucket_id = null; + } + return target.update(updatedAttrs); } diff --git a/addons/api/mirage/scenarios/default.js b/addons/api/mirage/scenarios/default.js index 8b90d290c..893a2fd0f 100644 --- a/addons/api/mirage/scenarios/default.js +++ b/addons/api/mirage/scenarios/default.js @@ -94,6 +94,10 @@ export default function (server) { role.update({ managedGroups }); }); + // Storage Buckets + server.createList('storage-bucket', 3, { scope: globalScope }); + server.createList('storage-bucket', 2, { scope: orgScope }); + // Other resources server.schema.scopes.where({ type: 'project' }).models.forEach((scope) => { server.createList('host-catalog', 8, { scope }, 'withChildren'); @@ -110,9 +114,7 @@ export default function (server) { // Workers server.createList('worker', 3, { scope: globalScope }); - // Session Recordings and Storage Buckets - server.createList('storage-bucket', 3, { scope: globalScope }); - server.createList('storage-bucket', 2, { scope: orgScope }); + // Session Recordings server.createList( 'session-recording', 3, From 458fd167e3bd30c5df446b827326514e6ca86212 Mon Sep 17 00:00:00 2001 From: Devon Anderson Date: Thu, 23 Mar 2023 12:33:31 -0400 Subject: [PATCH 078/193] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20create=20edit=20?= =?UTF-8?q?storage-bucket=20view=20(#137)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 🎸 create edit storage-bucket view Create edit storage bucket view for single storage bucket βœ… Closes: ICU-8240 * Update ui/admin/tests/acceptance/storage-buckets/update-test.js Co-authored-by: Zhihe Li * Update ui/admin/tests/acceptance/storage-buckets/update-test.js Co-authored-by: Zhihe Li * refactor: πŸ’‘ merge upstream merge upstream βœ… Closes: ICU-8240 * Update update-test.js removed unneeded await on assertion --------- Co-authored-by: Zhihe Li --- .../components/form/storage-bucket/index.hbs | 56 ++++++----- .../scope/storage-buckets/storage-bucket.js | 13 +++ .../scopes/scope/storage-buckets/new.js | 13 +-- .../storage-buckets/storage-bucket/index.js | 30 +++++- .../storage-buckets/storage-bucket/index.hbs | 39 +++++++- .../acceptance/storage-buckets/update-test.js | 98 +++++++++++++++++++ .../storage-buckets/storage-bucket-test.js | 16 +++ 7 files changed, 227 insertions(+), 38 deletions(-) create mode 100644 ui/admin/app/controllers/scopes/scope/storage-buckets/storage-bucket.js create mode 100644 ui/admin/tests/acceptance/storage-buckets/update-test.js create mode 100644 ui/admin/tests/unit/controllers/scopes/scope/storage-buckets/storage-bucket-test.js diff --git a/ui/admin/app/components/form/storage-bucket/index.hbs b/ui/admin/app/components/form/storage-bucket/index.hbs index 2413fd29f..27e5abe80 100644 --- a/ui/admin/app/components/form/storage-bucket/index.hbs +++ b/ui/admin/app/components/form/storage-bucket/index.hbs @@ -60,9 +60,9 @@ as |F| > {{t 'resources.storage-bucket.form.scope.label'}} - {{t - 'resources.storage-bucket.form.scope.help' - }} + + {{t 'resources.storage-bucket.form.scope.help'}} + {{#each @scopes as |scope|}} @@ -187,30 +187,32 @@ {{/if}} - - {{t - 'resources.storage-bucket.form.secret_access_key.label' - }} - {{t - 'resources.storage-bucket.form.secret_access_key.help' - }} - {{#if @model.errors.secret_access_key}} - - {{#each @model.errors.secret_access_key as |error|}} - {{error.message}} - {{/each}} - - {{/if}} - + {{#if @model.isNew}} + + {{t + 'resources.storage-bucket.form.secret_access_key.label' + }} + {{t + 'resources.storage-bucket.form.secret_access_key.help' + }} + {{#if @model.errors.secret_access_key}} + + {{#each @model.errors.secret_access_key as |error|}} + {{error.message}} + {{/each}} + + {{/if}} + + {{/if}} ({ model: scope })); - if (currentScope.id === 'global') { - scopes = [{ model: currentScope }, ...orgScopes]; - } else { - scopes = [ - { model: this.store.peekRecord('scope', 'global') }, - ...orgScopes, - ]; - } + scopes = [ + { model: this.store.peekRecord('scope', 'global') }, + ...orgScopes, + ]; this.scopes = scopes; } diff --git a/ui/admin/app/routes/scopes/scope/storage-buckets/storage-bucket/index.js b/ui/admin/app/routes/scopes/scope/storage-buckets/storage-bucket/index.js index 687ffc78a..e2a7c1f89 100644 --- a/ui/admin/app/routes/scopes/scope/storage-buckets/storage-bucket/index.js +++ b/ui/admin/app/routes/scopes/scope/storage-buckets/storage-bucket/index.js @@ -4,5 +4,33 @@ */ import Route from '@ember/routing/route'; +import { inject as service } from '@ember/service'; -export default class ScopesScopeStorageBucketsStorageBucketIndexRoute extends Route {} +export default class ScopesScopeStorageBucketsStorageBucketIndexRoute extends Route { + // =services + + @service store; + + // =methods + + async afterModel() { + let scopes; + const orgScopes = ( + await this.store.query('scope', { scope_id: 'global' }) + ).map((scope) => ({ model: scope })); + scopes = [ + { model: this.store.peekRecord('scope', 'global') }, + ...orgScopes, + ]; + this.scopes = scopes; + } + + /** + * Adds available global and org scopes to the context. + * @param {Controller} controller + */ + setupController(controller) { + super.setupController(...arguments); + controller.set('scopes', this.scopes); + } +} diff --git a/ui/admin/app/templates/scopes/scope/storage-buckets/storage-bucket/index.hbs b/ui/admin/app/templates/scopes/scope/storage-buckets/storage-bucket/index.hbs index 3faf92ead..1ce337527 100644 --- a/ui/admin/app/templates/scopes/scope/storage-buckets/storage-bucket/index.hbs +++ b/ui/admin/app/templates/scopes/scope/storage-buckets/storage-bucket/index.hbs @@ -1,4 +1,41 @@ {{! Copyright (c) HashiCorp, Inc. SPDX-License-Identifier: MPL-2.0 -}} \ No newline at end of file +}} + + + + + + + +

+ {{t 'resources.storage-bucket.title'}} + +

+ + {{@model.id}} + +
+ + + + + {{t 'titles.details'}} + + + + + + + +
\ No newline at end of file diff --git a/ui/admin/tests/acceptance/storage-buckets/update-test.js b/ui/admin/tests/acceptance/storage-buckets/update-test.js new file mode 100644 index 000000000..2b016ccb5 --- /dev/null +++ b/ui/admin/tests/acceptance/storage-buckets/update-test.js @@ -0,0 +1,98 @@ +import { module, test } from 'qunit'; +import { visit, click, fillIn } from '@ember/test-helpers'; +import { setupApplicationTest } from 'ember-qunit'; +import setupMirage from 'ember-cli-mirage/test-support/setup-mirage'; +import { Response } from 'miragejs'; +import { + authenticateSession, + // These are left here intentionally for future reference. + //currentSession, + //invalidateSession, +} from 'ember-simple-auth/test-support'; + +module('Acceptance | storage-buckets | update', function (hooks) { + setupApplicationTest(hooks); + setupMirage(hooks); + + let features; + + const instances = { + scopes: { + global: null, + }, + storageBucket: null, + }; + + const urls = { + globalScope: null, + storageBuckets: null, + storageBucket: null, + }; + + hooks.beforeEach(function () { + instances.scopes.global = this.server.create('scope', { id: 'global' }); + instances.storageBucket = this.server.create('storage-bucket', { + scope: instances.scopes.global, + }); + urls.globalScope = `/scopes/global`; + urls.storageBuckets = `${urls.globalScope}/storage-buckets`; + (urls.storageBucket = `${urls.storageBuckets}/${instances.storageBucket.id}`), + (features = this.owner.lookup('service:features')); + features.enable('session-recording'); + authenticateSession({}); + }); + + test('can save changes to an existing storage-bucket', async function (assert) { + assert.expect(2); + await visit(urls.storageBucket); + await click('form [type="button"]', 'Click edit mode'); + await fillIn('[name="name"]', 'Updated storage-bucket name'); + await click('.rose-form-actions [type="submit"]'); + assert.dom(`[href="${urls.storageBucket}"]`).isVisible(); + assert + .dom('input[name="name"]') + .hasValue('Updated storage-bucket name'); + }); + + test('can cancel changes to an existing storage-bucket', async function (assert) { + assert.expect(1); + const name = instances.storageBucket.name; + await visit(urls.storageBucket); + await click('form [type="button"]', 'Click edit mode'); + await fillIn('[name="name"]', 'Updated storage-bucket name'); + await click('.rose-form-actions [type="button"]'); + await assert.dom('input[name="name"]').hasValue(`${name}`); + }); + + test('saving an existing storage-bucket with invalid fields will display error messages', async function (assert) { + assert.expect(2); + await visit(urls.storageBuckets); + this.server.patch('/storage-buckets/:id', () => { + return new Response( + 400, + {}, + { + status: 400, + code: 'invalid_argument', + message: 'The request was invalid.', + details: { + request_fields: [ + { + name: 'region', + description: 'Region is required.', + }, + ], + }, + } + ); + }); + + await click(`[href="${urls.storageBucket}"]`); + await click('.rose-form-actions [type="button"]', 'Activate edit mode'); + await fillIn('[name="region"]', 'random string'); + await click('[type="submit"]'); + + assert.dom('[role="alert"] div').hasText('The request was invalid.'); + assert.dom('.hds-form-error__message').hasText('Region is required.'); + }); +}); diff --git a/ui/admin/tests/unit/controllers/scopes/scope/storage-buckets/storage-bucket-test.js b/ui/admin/tests/unit/controllers/scopes/scope/storage-buckets/storage-bucket-test.js new file mode 100644 index 000000000..d924847b6 --- /dev/null +++ b/ui/admin/tests/unit/controllers/scopes/scope/storage-buckets/storage-bucket-test.js @@ -0,0 +1,16 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'admin/tests/helpers'; + +module( + 'Unit | Controller | scopes/scope/storage-buckets/storage-bucket', + function (hooks) { + setupTest(hooks); + + test('it exists', function (assert) { + let controller = this.owner.lookup( + 'controller:scopes/scope/storage-buckets/storage-bucket' + ); + assert.ok(controller); + }); + } +); From d503b614bccab2501182573e5b51b2b16297c9e8 Mon Sep 17 00:00:00 2001 From: Zhihe Li Date: Thu, 23 Mar 2023 16:18:45 -0400 Subject: [PATCH 079/193] =?UTF-8?q?refactor:=20=F0=9F=92=A1=20Fix=20mirage?= =?UTF-8?q?=20data=20(#147)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- addons/api/mirage/config.js | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/addons/api/mirage/config.js b/addons/api/mirage/config.js index e2a31192f..a5b9a1e7d 100644 --- a/addons/api/mirage/config.js +++ b/addons/api/mirage/config.js @@ -659,7 +659,15 @@ function routes() { }); // storage-buckets - this.get('/storage-buckets'); + this.get( + '/storage-buckets', + ({ storageBuckets }, { queryParams: { scope_id: scopeId, recursive } }) => { + if (recursive && scopeId === 'global') { + return storageBuckets.all(); + } + return storageBuckets.where({ scopeId }); + } + ); this.get('/storage-buckets/:id'); this.del('/storage-buckets/:id'); this.patch('/storage-buckets/:id'); @@ -683,12 +691,7 @@ function routes() { ); // session recordings - this.get( - '/session-recordings', - ({ sessionRecordings }, { queryParams: { scope_id: scopeId } }) => { - return sessionRecordings.where({ scopeId }); - } - ); + this.get('/session-recordings'); this.get( '/session-recordings/:idMethod', async ({ sessionRecordings }, { params: { idMethod } }) => { From b5045f18515bd7f422c6de98b0a8647394871e7f Mon Sep 17 00:00:00 2001 From: Cameron Perera Date: Thu, 23 Mar 2023 15:55:10 -0500 Subject: [PATCH 080/193] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20add=20empty=20st?= =?UTF-8?q?ate=20views=20for=20session=20recordings=20screen=20(#145)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: πŸ€– rebase session-recording * refactor: πŸ’‘ update calls to fetch recordings and buckets --- addons/core/translations/resources/en-us.yaml | 5 +++ .../scopes/scope/session-recordings/index.js | 19 ++++++++++++ .../routes/scopes/scope/session-recordings.js | 17 +++++++--- .../scopes/scope/session-recordings/index.hbs | 31 +++++++++++++++++-- .../scope/session-recordings/index-test.js | 16 ++++++++++ 5 files changed, 81 insertions(+), 7 deletions(-) create mode 100644 ui/admin/app/controllers/scopes/scope/session-recordings/index.js create mode 100644 ui/admin/tests/unit/controllers/scopes/scope/session-recordings/index-test.js diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml index 5097060a7..59244dd21 100644 --- a/addons/core/translations/resources/en-us.yaml +++ b/addons/core/translations/resources/en-us.yaml @@ -233,6 +233,11 @@ session-recording: label: Target duration: label: Duration + messages: + none: + title: Welcome to session recording + description: Review, playback, and download recorded sessions. To get started, configure recording on a target and start a session. + no-storage-bucket-description: To start using session recordings, create a storage bucket and configure recording on a target. storage-bucket: title: Storage Bucket title_plural: Storage Buckets diff --git a/ui/admin/app/controllers/scopes/scope/session-recordings/index.js b/ui/admin/app/controllers/scopes/scope/session-recordings/index.js new file mode 100644 index 000000000..ee4b8092b --- /dev/null +++ b/ui/admin/app/controllers/scopes/scope/session-recordings/index.js @@ -0,0 +1,19 @@ +import Controller from '@ember/controller'; + +export default class ScopesScopeSessionRecordingsIndexController extends Controller { + /** + * Returns true if any session recordings exist + * @type {boolean} + */ + get hasSessionRecordings() { + return this.model.sessionRecordings.length > 0; + } + + /** + * Returns true if any storage buckets exist + * @type {boolean} + */ + get hasSessionRecordingsConfigured() { + return this.model.storageBuckets.length > 0; + } +} diff --git a/ui/admin/app/routes/scopes/scope/session-recordings.js b/ui/admin/app/routes/scopes/scope/session-recordings.js index 1f45a3e95..9b121c822 100644 --- a/ui/admin/app/routes/scopes/scope/session-recordings.js +++ b/ui/admin/app/routes/scopes/scope/session-recordings.js @@ -20,14 +20,21 @@ export default class ScopesScopeSessionRecordingsRoute extends Route { /** * Load all session recordings. - * @return {SessionRecordingModel} + * @return {{sessionRecordings: Array, storageBuckets: Array}} */ - model() { - // TODO: awaiting modeled data + async model() { const scope = this.modelFor('scopes.scope'); - const { id: scope_id } = scope; // if (this.can.can('list session-recording', scope, { collection: 'session-recordings' })) { - return this.store.query('session-recording', { scope_id }); + const { id: scope_id } = scope; + const sessionRecordings = await this.store.findAll('session-recording'); + const storageBuckets = await this.store.query('storage-bucket', { + scope_id, + recursive: true, + }); + return { + sessionRecordings, + storageBuckets, + }; // } } diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs index 8a7d8b86e..7bcc9e1f9 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs @@ -8,9 +8,9 @@ - {{#if @model}} + {{#if this.hasSessionRecordings}} + {{else}} + + + + {{#if this.hasSessionRecordingsConfigured}} + {{! storage buckets exist but no recordings }} + {{t 'resources.session-recording.messages.none.description'}} + {{else}} + {{! No storage buckets exist }} + {{t + 'resources.session-recording.messages.none.no-storage-bucket-description' + }} + {{/if}} + + {{#unless this.hasSessionRecordingsConfigured}} + + {{/unless}} + + {{/if}} \ No newline at end of file diff --git a/ui/admin/tests/unit/controllers/scopes/scope/session-recordings/index-test.js b/ui/admin/tests/unit/controllers/scopes/scope/session-recordings/index-test.js new file mode 100644 index 000000000..03ad5a50c --- /dev/null +++ b/ui/admin/tests/unit/controllers/scopes/scope/session-recordings/index-test.js @@ -0,0 +1,16 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'admin/tests/helpers'; + +module( + 'Unit | Controller | scopes/scope/session-recordings/index', + function (hooks) { + setupTest(hooks); + + test('it exists', function (assert) { + let controller = this.owner.lookup( + 'controller:scopes/scope/session-recordings/index' + ); + assert.ok(controller); + }); + } +); From e460a5e4293078da71c5029248f19fcc81ccfa8f Mon Sep 17 00:00:00 2001 From: Zhihe Li Date: Fri, 24 Mar 2023 10:52:55 -0400 Subject: [PATCH 081/193] =?UTF-8?q?chore:=20=F0=9F=A4=96=20Update=20models?= =?UTF-8?q?=20to=20new=20field=20names=20(#149)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- addons/api/addon/generated/models/channel-recording.js | 4 ++-- addons/api/addon/generated/models/connection-recording.js | 4 ++-- addons/api/addon/generated/models/session-recording.js | 4 ++-- addons/api/mirage/generated/factories/channel-recording.js | 6 +++--- .../api/mirage/generated/factories/connection-recording.js | 6 +++--- addons/api/mirage/generated/factories/session-recording.js | 6 +++--- .../app/templates/scopes/scope/session-recordings/index.hbs | 2 +- 7 files changed, 16 insertions(+), 16 deletions(-) diff --git a/addons/api/addon/generated/models/channel-recording.js b/addons/api/addon/generated/models/channel-recording.js index 65e1a044b..77f5dbc5c 100644 --- a/addons/api/addon/generated/models/channel-recording.js +++ b/addons/api/addon/generated/models/channel-recording.js @@ -43,13 +43,13 @@ export default class GeneratedChannelRecordingModel extends BaseModel { description: 'The time the Channel started.', readOnly: true, }) - started_time; + start_time; @attr('date', { description: 'The time the Channel finished.', readOnly: true, }) - finished_time; + end_time; @attr({ description: 'The array of mime types that this recording will support.', diff --git a/addons/api/addon/generated/models/connection-recording.js b/addons/api/addon/generated/models/connection-recording.js index e78f77b8b..66688e07d 100644 --- a/addons/api/addon/generated/models/connection-recording.js +++ b/addons/api/addon/generated/models/connection-recording.js @@ -44,13 +44,13 @@ export default class GeneratedConnectionRecordingModel extends BaseModel { description: 'The time the Connection started.', readOnly: true, }) - started_time; + start_time; @attr('date', { description: 'The time the Connection finished.', readOnly: true, }) - finished_time; + end_time; @attr({ description: 'The array of mime types that this recording will support.', diff --git a/addons/api/addon/generated/models/session-recording.js b/addons/api/addon/generated/models/session-recording.js index b52c7370b..1b544406b 100644 --- a/addons/api/addon/generated/models/session-recording.js +++ b/addons/api/addon/generated/models/session-recording.js @@ -61,13 +61,13 @@ export default class GeneratedSessionRecordingModel extends BaseModel { description: 'The time the Session started.', readOnly: true, }) - started_time; + start_time; @attr('date', { description: 'The time the Session finished.', readOnly: true, }) - finished_time; + end_time; @attr('date', { description: 'The time the Session recording was last updated.', diff --git a/addons/api/mirage/generated/factories/channel-recording.js b/addons/api/mirage/generated/factories/channel-recording.js index 75b0b0c5b..7e3ee6c47 100644 --- a/addons/api/mirage/generated/factories/channel-recording.js +++ b/addons/api/mirage/generated/factories/channel-recording.js @@ -13,10 +13,10 @@ export default Factory.extend({ bytes_up: () => faker.datatype.number(), bytes_down: () => faker.datatype.number(), errors: () => faker.datatype.number({ max: 10 }), - started_time() { - return faker.date.recent(3, this.finished_time); + start_time() { + return faker.date.recent(3, this.end_time); }, - finished_time: () => faker.date.recent(), + end_time: () => faker.date.recent(), duration: () => `${faker.datatype.number()}s`, mime_types: () => ['application/x-asciicast'], }); diff --git a/addons/api/mirage/generated/factories/connection-recording.js b/addons/api/mirage/generated/factories/connection-recording.js index 17f7b1583..943b47533 100644 --- a/addons/api/mirage/generated/factories/connection-recording.js +++ b/addons/api/mirage/generated/factories/connection-recording.js @@ -13,9 +13,9 @@ export default Factory.extend({ bytes_up: () => faker.datatype.number(), bytes_down: () => faker.datatype.number(), errors: () => faker.datatype.number({ max: 10 }), - started_time() { - return faker.date.recent(3, this.finished_time); + start_time() { + return faker.date.recent(3, this.end_time); }, - finished_time: () => faker.date.recent(), + end_time: () => faker.date.recent(), duration: () => `${faker.datatype.number()}s`, }); diff --git a/addons/api/mirage/generated/factories/session-recording.js b/addons/api/mirage/generated/factories/session-recording.js index 07032faf3..379d671c1 100644 --- a/addons/api/mirage/generated/factories/session-recording.js +++ b/addons/api/mirage/generated/factories/session-recording.js @@ -13,10 +13,10 @@ export default Factory.extend({ bytes_up: () => faker.datatype.number(), bytes_down: () => faker.datatype.number(), errors: () => faker.datatype.number({ max: 10 }), - started_time() { - return faker.date.recent(3, this.finished_time); + start_time() { + return faker.date.recent(3, this.end_time); }, - finished_time() { + end_time() { return faker.date.recent(1, this.updated_time); }, updated_time: () => faker.date.recent(), diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs index 7bcc9e1f9..10f3bafb0 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs @@ -24,7 +24,7 @@ - {{format-date B.data.started_time format='mmddyyhhmm'}} + {{format-date B.data.start_time format='mmddyyhhmm'}} From 85f2561a729f231f6a778336978cb6afb3d042cc Mon Sep 17 00:00:00 2001 From: Devon Anderson Date: Fri, 24 Mar 2023 11:17:06 -0400 Subject: [PATCH 082/193] Icu 8559 use secret input component for access key (#146) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 🎸 create edit storage-bucket view Create edit storage bucket view for single storage bucket βœ… Closes: ICU-8240 * Update ui/admin/tests/acceptance/storage-buckets/update-test.js Co-authored-by: Zhihe Li * Update ui/admin/tests/acceptance/storage-buckets/update-test.js Co-authored-by: Zhihe Li * refactor: πŸ’‘ merge upstream merge upstream βœ… Closes: ICU-8240 * feat: 🎸 implement secret-input component Implement `secret-input` component for `access_key_id` field in the `storage-bucket` new and edit forms. βœ… Closes: ICU-8559 * refactor: πŸ’‘ refactored storage-bucket form We will still conditionally render regular `Hds::Form::TextInput::Field` for new `storage-bucket` and render `Form::Field::SecretInput` for detail view and edit view. βœ… Closes: ICU-8559 * refactor: πŸ’‘ fixed failing test for storage bucket from Fixed failing test for edit button now that secret-input has been implemented βœ… Closes: ICU-8559 * Update ui/admin/app/components/form/storage-bucket/index.hbs Co-authored-by: Zhihe Li * Update index.js --------- Co-authored-by: Zhihe Li --- .../components/form/storage-bucket/index.hbs | 74 +++++++++++++------ .../acceptance/storage-buckets/update-test.js | 8 +- 2 files changed, 55 insertions(+), 27 deletions(-) diff --git a/ui/admin/app/components/form/storage-bucket/index.hbs b/ui/admin/app/components/form/storage-bucket/index.hbs index 27e5abe80..7563e7b61 100644 --- a/ui/admin/app/components/form/storage-bucket/index.hbs +++ b/ui/admin/app/components/form/storage-bucket/index.hbs @@ -164,28 +164,58 @@ {{/if}}
- - {{t 'resources.storage-bucket.form.access_key_id.label'}} - {{t - 'resources.storage-bucket.form.access_key_id.help' - }} - {{#if @model.errors.access_key_id}} - - {{#each @model.errors.access_key_id as |error|}} - {{error.message}} - {{/each}} - - {{/if}} - + {{#if @model.isNew}} + + {{t + 'resources.storage-bucket.form.access_key_id.label' + }} + {{t + 'resources.storage-bucket.form.access_key_id.help' + }} + {{#if @model.errors.access_key_id}} + + {{#each @model.errors.access_key_id as |error|}} + {{error.message}} + {{/each}} + + {{/if}} + + {{else}} + + {{t + 'resources.storage-bucket.form.access_key_id.label' + }} + {{t + 'resources.storage-bucket.form.access_key_id.help' + }} + {{#if @model.errors.access_key_id}} + + {{#each @model.errors.access_key_id as |error|}} + {{error.message}} + {{/each}} + + {{/if}} + + {{/if}} {{#if @model.isNew}} Date: Fri, 24 Mar 2023 11:51:55 -0400 Subject: [PATCH 083/193] =?UTF-8?q?refactor:=20=F0=9F=92=A1=20Update=20sto?= =?UTF-8?q?rage=20bucket=20route=20to=20use=20recursive=20(#150)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ui/admin/app/routes/scopes/scope/storage-buckets.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/admin/app/routes/scopes/scope/storage-buckets.js b/ui/admin/app/routes/scopes/scope/storage-buckets.js index ca713dd12..f762261fb 100644 --- a/ui/admin/app/routes/scopes/scope/storage-buckets.js +++ b/ui/admin/app/routes/scopes/scope/storage-buckets.js @@ -28,7 +28,7 @@ export default class ScopesScopeStorageBucketsRoute extends Route { /** * Load all storage buckets under current scope. - * @return {Promise{[StorageBucketModel]}} + * @return {Promise<[StorageBucketModel]>} */ async model() { const scope = this.modelFor('scopes.scope'); @@ -38,7 +38,7 @@ export default class ScopesScopeStorageBucketsRoute extends Route { collection: 'storage-buckets', }) ) { - return this.store.query('storage-bucket', { scope_id }); + return this.store.query('storage-bucket', { scope_id, recursive: true }); } } From 20ef3a3b9e9d86fc99e0bd04aafd77d3cfeb7bac Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Corvo Date: Fri, 24 Mar 2023 10:28:29 -0700 Subject: [PATCH 084/193] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20Add=20Channel=20?= =?UTF-8?q?data=20from=20mirage=20(#151)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 🎸 Add Channel data from mirage βœ… Closes: ICU-8635 --- addons/core/translations/resources/en-us.yaml | 1 + .../channels-by-connection/channel.js | 11 ++++- .../channels-by-connection/channel.hbs | 48 ++++++++++++++++++- 3 files changed, 57 insertions(+), 3 deletions(-) diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml index 59244dd21..75cda1d12 100644 --- a/addons/core/translations/resources/en-us.yaml +++ b/addons/core/translations/resources/en-us.yaml @@ -222,6 +222,7 @@ session-recording: channel: title: Channel title_plural: Channels + details: Channel details session: title: Session Playback form: diff --git a/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.js b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.js index 037f8ee20..57fc48f2e 100644 --- a/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.js +++ b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.js @@ -7,11 +7,20 @@ export default class ScopesScopeSessionRecordingsSessionRecordingChannelsByConne // =methods async model({ channel_id }) { + const sessionRecording = await this.modelFor( + 'scopes.scope.session-recordings.session-recording' + ); + const channelRecording = await this.store.peekRecord( + 'channel-recording', + channel_id + ); + const response = await fetch('/session.cast'); const asciicast = await response.text(); return { - channel_id: channel_id, + channelRecording, + sessionRecording, asciicast: asciicast, }; } diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs index 57ede0481..f6864ee05 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs @@ -6,7 +6,8 @@ -

{{t 'resources.session-recording.channel.title'}}

+

{{t 'resources.session-recording.channel.title'}} + {{@model.channelRecording.id}}

@@ -16,7 +17,50 @@ -

{{@model.channel_id}}

+
+

{{t 'resources.session-recording.channel.details'}}

+ {{! Started time }} +

+ + {{@model.channelRecording.started_time}} +

+ + {{! Created By }} +

+ + {{@model.sessionRecording.user.name}} +

+ + {{! Type }} +

+ + {{@model.sessionRecording.type}} +

+ + {{! Duration }} +

+ + {{@model.channelRecording.duration}} +

+ + {{! Bytes up }} +

+ + {{@model.channelRecording.bytes_up}} +

+ + {{! Bytes down }} +

+ + {{@model.channelRecording.bytes_down}} +

+ + {{! Errors }} +

+ + {{@model.channelRecording.errors}} +

+
From 304b76cb69987ae8299dc4323646f82b971eed47 Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Corvo Date: Fri, 24 Mar 2023 16:27:21 -0700 Subject: [PATCH 085/193] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Fix=20breadcrumb?= =?UTF-8?q?=20and=20field=20name=20(#153)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix breadcrumb and field name --- .../session-recording/channels-by-connection/channel.js | 2 +- .../session-recording/channels-by-connection/channel.hbs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ui/admin/app/controllers/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.js b/ui/admin/app/controllers/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.js index 5853cd990..941c9f3a0 100644 --- a/ui/admin/app/controllers/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.js +++ b/ui/admin/app/controllers/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.js @@ -10,6 +10,6 @@ export default class ScopesScopeSessionRecordingsSessionRecordingChannelsByConne * Session recording channel breadcrumb */ get breadCrumb() { - return this.model.channel_id; + return this.model.channelRecording.id; } } diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs index f6864ee05..14e5eb47a 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs @@ -19,10 +19,10 @@

{{t 'resources.session-recording.channel.details'}}

- {{! Started time }} + {{! Start time }}

- {{@model.channelRecording.started_time}} + {{@model.channelRecording.start_time}}

{{! Created By }} From 97588e88c75d8cb93b18b3538f6a9cc5ca7ca9b0 Mon Sep 17 00:00:00 2001 From: Zhihe Li Date: Mon, 27 Mar 2023 11:11:38 -0400 Subject: [PATCH 086/193] =?UTF-8?q?refactor:=20=F0=9F=92=A1=20Update=20mir?= =?UTF-8?q?age=20data=20(#157)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- addons/api/mirage/factories/session-recording.js | 10 ++++++++++ addons/api/mirage/serializers/session-recording.js | 2 ++ 2 files changed, 12 insertions(+) diff --git a/addons/api/mirage/factories/session-recording.js b/addons/api/mirage/factories/session-recording.js index 7d7977b4b..acdbc8788 100644 --- a/addons/api/mirage/factories/session-recording.js +++ b/addons/api/mirage/factories/session-recording.js @@ -33,6 +33,11 @@ export default factory.extend({ const target = session.target; target.id = 'deleted_target'; + const storageBucket = pickRandomElement( + server.schema.storageBuckets.all().models + ); + target.storage_bucket_id = storageBucket.id; + sessionRecording.update({ user, target, @@ -47,6 +52,11 @@ export default factory.extend({ const session = pickRandomElement(server.schema.sessions.all().models); const target = session.target; + const storageBucket = pickRandomElement( + server.schema.storageBuckets.all().models + ); + target.storage_bucket_id = storageBucket.id; + sessionRecording.update({ user, target, diff --git a/addons/api/mirage/serializers/session-recording.js b/addons/api/mirage/serializers/session-recording.js index 59eb43c67..4a0d3943c 100644 --- a/addons/api/mirage/serializers/session-recording.js +++ b/addons/api/mirage/serializers/session-recording.js @@ -36,6 +36,8 @@ export default ApplicationSerializer.extend({ json.target = TargetSerializer.prototype._hashForModel.apply(this, [ target, ]); + json.target.scope.name = model.target.scope.name; + json.target.scope.description = model.target.scope.description; } json.session_id = model.sessionId; From 983eee2742575f1109c6d830e4b31672a100075f Mon Sep 17 00:00:00 2001 From: Cameron Perera Date: Mon, 27 Mar 2023 11:43:05 -0500 Subject: [PATCH 087/193] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20move=20channel?= =?UTF-8?q?=20info=20to=20HDS=20table=20(#154)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 🎸 move channel info to HDS table βœ… Closes: ICU-8609 * refactor: πŸ’‘ change standalone link to hds.button * refactor: πŸ’‘ use hds typography tokens for table titles --- addons/core/translations/resources/en-us.yaml | 7 ++ ui/admin/app/styles/app.scss | 7 ++ .../session-recording/index.hbs | 98 ++++++++++++++----- .../session-recording-test.js | 25 ++++- 4 files changed, 110 insertions(+), 27 deletions(-) diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml index 75cda1d12..89bff1130 100644 --- a/addons/core/translations/resources/en-us.yaml +++ b/addons/core/translations/resources/en-us.yaml @@ -217,6 +217,13 @@ session-recording: connection: title: Connection title_plural: Connections + form: + channel: + label: Channel + type: + label: Type + summary: + label: Summary channels-by-connection: title: Channels by connection channel: diff --git a/ui/admin/app/styles/app.scss b/ui/admin/app/styles/app.scss index 4090dac4f..24532d74a 100644 --- a/ui/admin/app/styles/app.scss +++ b/ui/admin/app/styles/app.scss @@ -804,3 +804,10 @@ align-items: center; } } + +// Channels by Connection +.channels-by-connection { + &-connection-header { + padding: 0.875rem 1rem; + } +} diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs index acd86daed..5c89e63a4 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs @@ -8,32 +8,78 @@ - - -

- {{t 'resources.session-recording.title'}} - {{@model.id}} -

- - {{#each @model.connection_recordings as |connection|}} -

{{t 'resources.session-recording.connection.title'}} - {{connection.id}}

- {{#each connection.channel_recordings as |channel|}} -

- - {{channel.id}} - -

+
+ + + {{#each @model.connection_recordings as |connection|}} +
+

+ {{t 'resources.session-recording.connection.title'}} + {{connection.id}} +

+
+ + <:body as |B|> + + + {{B.data.id}} + + + {{B.data.type}} + + + + {{B.data.bytes_up}} + + {{B.data.bytes_down}} + + + + {{format-time-duration B.data.duration}} + + + + + + + + + {{/each}} - {{/each}} -
- - -

{{t 'actions.help'}}

-
-
+ + +

{{t 'actions.help'}}

+
+ +
\ No newline at end of file diff --git a/ui/admin/tests/acceptance/session-recordings/session-recording/session-recording-test.js b/ui/admin/tests/acceptance/session-recordings/session-recording/session-recording-test.js index 5177f2a56..0a91ad99d 100644 --- a/ui/admin/tests/acceptance/session-recordings/session-recording/session-recording-test.js +++ b/ui/admin/tests/acceptance/session-recordings/session-recording/session-recording-test.js @@ -1,5 +1,5 @@ import { module, test } from 'qunit'; -import { visit, currentURL } from '@ember/test-helpers'; +import { visit, currentURL, click } from '@ember/test-helpers'; import { setupApplicationTest } from 'admin/tests/helpers'; import setupMirage from 'ember-cli-mirage/test-support/setup-mirage'; import { authenticateSession } from 'ember-simple-auth/test-support'; @@ -8,6 +8,10 @@ module('Acceptance | session recordings | session recording', function (hooks) { setupApplicationTest(hooks); setupMirage(hooks); + // Selectors + const LIST_CHANNEL_RECORDING_BUTTON = + 'table > tbody > tr > td:last-child > a'; + // Instances const instances = { scopes: { @@ -21,6 +25,7 @@ module('Acceptance | session recordings | session recording', function (hooks) { globalScope: null, sessionRecordings: null, sessionRecording: null, + channelRecording: null, }; hooks.beforeEach(function () { @@ -32,9 +37,16 @@ module('Acceptance | session recordings | session recording', function (hooks) { instances.sessionRecording = this.server.create('session-recording', { scope: instances.scopes.global, }); + instances.connectionRecording = this.server.create('connection-recording', { + session_recording: instances.sessionRecording, + }); + instances.channelRecording = this.server.create('channel-recording', { + connection_recording: instances.connectionRecording, + }); urls.globalScope = `/scopes/global`; urls.sessionRecordings = `${urls.globalScope}/session-recordings`; urls.sessionRecording = `${urls.sessionRecordings}/${instances.sessionRecording.id}`; + urls.channelRecording = `${urls.sessionRecording}/channels-by-connection/${instances.channelRecording.id}`; authenticateSession({}); }); @@ -45,4 +57,15 @@ module('Acceptance | session recordings | session recording', function (hooks) { await visit(urls.sessionRecording); assert.strictEqual(currentURL(), urls.sessionRecording); }); + + test('user can navigate to a channel recording', async function (assert) { + assert.expect(2); + + // Visit session recording + await visit(urls.sessionRecording); + assert.dom('table').hasClass('hds-table'); + // Click a channel recording and check it navigates properly + await click(LIST_CHANNEL_RECORDING_BUTTON); + assert.strictEqual(currentURL(), urls.channelRecording); + }); }); From f0e1101479826f0fe78455b4076b806282d79ffd Mon Sep 17 00:00:00 2001 From: Zhihe Li Date: Mon, 27 Mar 2023 14:46:34 -0400 Subject: [PATCH 088/193] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20Add=20abilities?= =?UTF-8?q?=20to=20target=20for=20storage=20buckets=20(#148)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit βœ… Closes: ICU-8081 --- addons/api/addon/abilities/target.js | 14 +++ .../api/tests/unit/abilities/target-test.js | 102 ++++++++++++++---- 2 files changed, 94 insertions(+), 22 deletions(-) diff --git a/addons/api/addon/abilities/target.js b/addons/api/addon/abilities/target.js index 00030ea3b..ee2040fa6 100644 --- a/addons/api/addon/abilities/target.js +++ b/addons/api/addon/abilities/target.js @@ -53,4 +53,18 @@ export default class TargetAbility extends ModelAbility { get canRemoveCredentialSources() { return this.hasAuthorizedAction('remove-credential-sources'); } + + /** + * @type {boolean} + */ + get canSetStorageBucket() { + return this.model.isSSH && this.hasAuthorizedAction('set-storage-bucket'); + } + + /** + * @type {boolean} + */ + get canRemoveStorageBucket() { + return this.hasAuthorizedAction('remove-storage-bucket'); + } } diff --git a/addons/api/tests/unit/abilities/target-test.js b/addons/api/tests/unit/abilities/target-test.js index 93ea738b0..6d170579d 100644 --- a/addons/api/tests/unit/abilities/target-test.js +++ b/addons/api/tests/unit/abilities/target-test.js @@ -9,74 +9,132 @@ import { setupTest } from 'ember-qunit'; module('Unit | Abilities | Target', function (hooks) { setupTest(hooks); + let canService; + + hooks.beforeEach(function () { + canService = this.owner.lookup('service:can'); + }); + test('it reflects when a given target may connect based on authorized_actions', function (assert) { assert.expect(2); - const service = this.owner.lookup('service:can'); const model = { authorized_actions: ['authorize-session'], }; - assert.ok(service.can('connect target', model)); + assert.true(canService.can('connect target', model)); model.authorized_actions = []; - assert.notOk(service.can('connect target', model)); + assert.false(canService.can('connect target', model)); }); test('it reflects when a given target may add host sources', function (assert) { assert.expect(2); - const service = this.owner.lookup('service:can'); const model = { authorized_actions: ['add-host-sources'], }; - assert.ok(service.can('addHostSources target', model)); + assert.true(canService.can('addHostSources target', model)); model.authorized_actions = []; - assert.notOk(service.can('addHostSources target', model)); + assert.false(canService.can('addHostSources target', model)); }); test('it reflects when a given target may remove host sources', function (assert) { assert.expect(2); - const service = this.owner.lookup('service:can'); const model = { authorized_actions: ['remove-host-sources'], }; - assert.ok(service.can('removeHostSources target', model)); + assert.true(canService.can('removeHostSources target', model)); model.authorized_actions = []; - assert.notOk(service.can('removeHostSources target', model)); + assert.false(canService.can('removeHostSources target', model)); }); test('it reflects when a given target may add brokered credential sources', function (assert) { assert.expect(2); - const service = this.owner.lookup('service:can'); const model = { authorized_actions: ['add-credential-sources'], }; - assert.ok(service.can('addBrokeredCredentialSources target', model)); + assert.true(canService.can('addBrokeredCredentialSources target', model)); model.authorized_actions = []; - assert.notOk(service.can('addBrokeredCredentialSources target', model)); + assert.false(canService.can('addBrokeredCredentialSources target', model)); }); test('it reflects when a given target may remove credential sources', function (assert) { assert.expect(2); - const service = this.owner.lookup('service:can'); const model = { authorized_actions: ['remove-credential-sources'], }; - assert.ok(service.can('removeCredentialSources target', model)); + assert.true(canService.can('removeCredentialSources target', model)); model.authorized_actions = []; - assert.notOk(service.can('removeCredentialSources target', model)); + assert.false(canService.can('removeCredentialSources target', model)); }); test('it reflects when a given ssh target may add injected application credential sources', function (assert) { - assert.expect(2); - const service = this.owner.lookup('service:can'); + assert.expect(3); const model = { authorized_actions: ['add-credential-sources'], isSSH: true, }; - assert.ok( - service.can('addInjectedApplicationCredentialSources target', model) + const modelWithoutAuthorizedActions = { + authorized_actions: [], + isSSH: true, + }; + const modelWithoutSSHType = { + authorized_actions: ['add-credential-sources'], + }; + + assert.true( + canService.can('addInjectedApplicationCredentialSources target', model) ); - model.authorized_actions = []; - assert.notOk( - service.can('addInjectedApplicationCredentialSources target', model) + assert.false( + canService.can( + 'addInjectedApplicationCredentialSources target', + modelWithoutAuthorizedActions + ) + ); + assert.false( + canService.can( + 'addInjectedApplicationCredentialSources target', + modelWithoutSSHType + ) + ); + }); + + test('it reflects when a given ssh target may set a storage bucket', function (assert) { + assert.expect(3); + const model = { + authorized_actions: ['set-storage-bucket'], + isSSH: true, + }; + const modelWithoutAuthorizedActions = { + authorized_actions: [], + isSSH: true, + }; + const modelWithoutSSHType = { + authorized_actions: ['set-storage-bucket'], + }; + + assert.true(canService.can('setStorageBucket target', model)); + assert.false( + canService.can('setStorageBucket target', modelWithoutAuthorizedActions) + ); + assert.false( + canService.can('setStorageBucket target', modelWithoutSSHType) + ); + }); + + test('it reflects when a given target may remove a storage bucket', function (assert) { + assert.expect(2); + const model = { + authorized_actions: ['remove-storage-bucket'], + }; + const modelWithoutAuthorizedActions = { + authorized_actions: [], + isSSH: true, + }; + + assert.true(canService.can('removeStorageBucket target', model)); + assert.false( + canService.can( + 'removeStorageBucket target', + modelWithoutAuthorizedActions + ) ); }); }); From 971ab2be61823023354adcec0c18811343a126ff Mon Sep 17 00:00:00 2001 From: Dharini Jeeva Date: Mon, 27 Mar 2023 13:38:32 -0700 Subject: [PATCH 089/193] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20target=20session?= =?UTF-8?q?=20recording=20configure=20on=20edit=20mode=20(#144)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 🎸 target session recording sidebar --- addons/core/translations/resources/en-us.yaml | 4 ++ ui/admin/app/styles/app.scss | 21 ++++++++++ .../scopes/scope/targets/target/index.hbs | 40 ++++++++++++++++--- 3 files changed, 60 insertions(+), 5 deletions(-) diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml index 89bff1130..d71b1f96e 100644 --- a/addons/core/translations/resources/en-us.yaml +++ b/addons/core/translations/resources/en-us.yaml @@ -384,6 +384,7 @@ target: add-injected-application-credential-sources: Add Injected Application Credentials remove-address: Remove address and save enable-session-recording: Enable Session Recording + enable-recording: Enable recording types: tcp: Generic TCP ssh: SSH @@ -400,6 +401,9 @@ target: worker_filter: label: Worker Filter help: Deprecated. Boolean expression to filter the workers that are allowed to satisfy this request. + sidebar: + label: Session Recording + help: Record SSH sessions on this target and save them to an Amazon S3 bucket. questions: delete-host-sources: title: Remove associated host sources? diff --git a/ui/admin/app/styles/app.scss b/ui/admin/app/styles/app.scss index 24532d74a..4131c3e5b 100644 --- a/ui/admin/app/styles/app.scss +++ b/ui/admin/app/styles/app.scss @@ -643,6 +643,27 @@ } } +// target sidebar +.target-sidebar { + .title-wrapper { + display: flex; + justify-content: space-between; + align-items: baseline; + + .hds-button { + box-shadow: none; + border: none; + background-color: transparent; + } + } + + .description { + color: var(--token-form-helper-text-color); + font-weight: var(--token-typography-font-weight-normal); + font-size: var(--token-typography-body-200-font-size); + } +} + .key-value-list { border: 0; diff --git a/ui/admin/app/templates/scopes/scope/targets/target/index.hbs b/ui/admin/app/templates/scopes/scope/targets/target/index.hbs index 87cedc69b..f0ce80553 100644 --- a/ui/admin/app/templates/scopes/scope/targets/target/index.hbs +++ b/ui/admin/app/templates/scopes/scope/targets/target/index.hbs @@ -22,11 +22,41 @@ - + + + + + + {{#if (can 'setStorageBucket target' @model)}} + +
+
+

{{t 'resources.target.form.sidebar.label'}}

+ +
+

+ {{t 'resources.target.form.sidebar.help'}} +

+ +
+
+ {{/if}} +
+
\ No newline at end of file From 2f5da06eec9583e46ed18b2e7f73d5cd40548e27 Mon Sep 17 00:00:00 2001 From: Zhihe Li Date: Tue, 28 Mar 2023 11:12:58 -0400 Subject: [PATCH 090/193] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Fix=20targets=20s?= =?UTF-8?q?ometimes=20not=20having=20a=20storage=20bucket=20id=20(#159)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- addons/api/mirage/factories/session-recording.js | 16 +++++----------- addons/api/mirage/factories/target.js | 5 +++-- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/addons/api/mirage/factories/session-recording.js b/addons/api/mirage/factories/session-recording.js index acdbc8788..39abefb7d 100644 --- a/addons/api/mirage/factories/session-recording.js +++ b/addons/api/mirage/factories/session-recording.js @@ -30,13 +30,10 @@ export default factory.extend({ user.id = 'deleted_user'; const session = pickRandomElement(server.schema.sessions.all().models); session.id = 'deleted_session'; - const target = session.target; - target.id = 'deleted_target'; - - const storageBucket = pickRandomElement( - server.schema.storageBuckets.all().models + const target = pickRandomElement( + server.schema.targets.where((target) => target.storage_bucket_id).models ); - target.storage_bucket_id = storageBucket.id; + target.id = 'deleted_target'; sessionRecording.update({ user, @@ -50,12 +47,9 @@ export default factory.extend({ afterCreate(sessionRecording, server) { const user = pickRandomElement(server.schema.users.all().models); const session = pickRandomElement(server.schema.sessions.all().models); - const target = session.target; - - const storageBucket = pickRandomElement( - server.schema.storageBuckets.all().models + const target = pickRandomElement( + server.schema.targets.where((target) => target.storage_bucket_id).models ); - target.storage_bucket_id = storageBucket.id; sessionRecording.update({ user, diff --git a/addons/api/mirage/factories/target.js b/addons/api/mirage/factories/target.js index 8a4a93cc6..36b990584 100644 --- a/addons/api/mirage/factories/target.js +++ b/addons/api/mirage/factories/target.js @@ -8,7 +8,7 @@ import { trait } from 'miragejs'; import { faker } from '@faker-js/faker'; import permissions from '../helpers/permissions'; import generateId from '../helpers/id'; -import { TYPES_TARGET } from 'api/models/target'; +import { TYPES_TARGET, TYPE_TARGET_SSH } from 'api/models/target'; const randomBoolean = (chance = 0.5) => Math.random() < chance; const hostSetChance = 0.3; @@ -72,7 +72,8 @@ export default factory.extend({ const randomlySelectedStorageBucket = faker.helpers.arrayElement( server.schema.storageBuckets.all().models ); - if (randomlySelectedStorageBucket && randomBoolean()) { + + if (randomlySelectedStorageBucket && target.type === TYPE_TARGET_SSH) { target.update({ storage_bucket_id: randomlySelectedStorageBucket.id }); } From b3dc1f236d73e95942df520884e66f7b83012005 Mon Sep 17 00:00:00 2001 From: lisbet-alvarez <107949262+lisbet-alvarez@users.noreply.github.com> Date: Tue, 28 Mar 2023 08:46:25 -0700 Subject: [PATCH 091/193] =?UTF-8?q?refactor:=20=F0=9F=92=A1=20use=20secret?= =?UTF-8?q?=20input=20component=20for=20secret=20access=20key=20(#156)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: πŸ’‘ use secret input component for secret access key use new component and update test files βœ… Closes: ICU-8645 * Update ui/admin/app/components/form/storage-bucket/index.hbs Co-authored-by: Zhihe Li * refactor: πŸ’‘ revise translation wording * style: πŸ’„ fix linting space issue * refactor: πŸ’‘ only rollback changes for specific attribute * style: πŸ’„ change button text color in dark mode for a11yAudit * refactor: πŸ’‘ add function to cancel changes to secrets * Update ui/admin/app/components/form/storage-bucket/index.js Co-authored-by: Zhihe Li --------- Co-authored-by: Zhihe Li --- addons/core/translations/resources/en-us.yaml | 4 +- .../styles/hds/themes/dark-mode/index.scss | 3 + .../components/form/storage-bucket/index.hbs | 90 ++++++++----- .../components/form/storage-bucket/index.js | 10 ++ .../routes/scopes/scope/storage-buckets.js | 2 +- .../{create-test-test.js => create-test.js} | 0 .../acceptance/storage-buckets/read-test.js | 36 +++++- .../acceptance/storage-buckets/update-test.js | 120 +++++++++++++++--- 8 files changed, 210 insertions(+), 55 deletions(-) rename ui/admin/tests/acceptance/storage-buckets/{create-test-test.js => create-test.js} (100%) diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml index d71b1f96e..3debadfdc 100644 --- a/addons/core/translations/resources/en-us.yaml +++ b/addons/core/translations/resources/en-us.yaml @@ -279,10 +279,10 @@ storage-bucket: help: The AWS region to use access_key_id: label: Access key ID - help: The Access key ID generated by AWS for the IAM User to use with this storage bucket. We will not show this data after it is saved, but you can replace. + help: The Access key ID generated by AWS for the IAM User to use with this storage bucket. We will not show this data after it is saved, but you can replace it. secret_access_key: label: Secret access key - help: The secret access key to use. + help: The secret access key generated by AWS for the IAM user to use with this storage bucket. We will not show this data after it is saved, but you can replace it. worker_filter: label: Worker filter help: Filter for Boundary workers that have network access to your storage. Boolean expression. diff --git a/addons/rose/addon/styles/hds/themes/dark-mode/index.scss b/addons/rose/addon/styles/hds/themes/dark-mode/index.scss index 14ab0905d..38ab4cf09 100644 --- a/addons/rose/addon/styles/hds/themes/dark-mode/index.scss +++ b/addons/rose/addon/styles/hds/themes/dark-mode/index.scss @@ -102,6 +102,9 @@ --token-color-palette-neutral-200 ); --token-form-indicator-optional-color: var(--token-color-palette-neutral-200); + --token-color-foreground-high-contrast: var( + --token-color-palette-neutral-700 + ); } @media (prefers-color-scheme: dark) { diff --git a/ui/admin/app/components/form/storage-bucket/index.hbs b/ui/admin/app/components/form/storage-bucket/index.hbs index 7563e7b61..18018710f 100644 --- a/ui/admin/app/components/form/storage-bucket/index.hbs +++ b/ui/admin/app/components/form/storage-bucket/index.hbs @@ -65,7 +65,12 @@ {{#each @scopes as |scope|}} - + {{/each}} @@ -188,36 +193,7 @@ {{/if}} - {{else}} - - {{t - 'resources.storage-bucket.form.access_key_id.label' - }} - {{t - 'resources.storage-bucket.form.access_key_id.help' - }} - {{#if @model.errors.access_key_id}} - - {{#each @model.errors.access_key_id as |error|}} - {{error.message}} - {{/each}} - - {{/if}} - - {{/if}} - {{#if @model.isNew}} {{/if}} + {{else}} + + {{t + 'resources.storage-bucket.form.access_key_id.label' + }} + {{t + 'resources.storage-bucket.form.access_key_id.help' + }} + {{#if @model.errors.access_key_id}} + + {{#each @model.errors.access_key_id as |error|}} + {{error.message}} + {{/each}} + + {{/if}} + + + + {{t + 'resources.storage-bucket.form.secret_access_key.label' + }} + {{t + 'resources.storage-bucket.form.secret_access_key.help' + }} + {{#if @model.errors.secret_access_key}} + + {{#each @model.errors.secret_access_key as |error|}} + {{error.message}} + {{/each}} + + {{/if}} + {{/if}} } */ async model() { diff --git a/ui/admin/tests/acceptance/storage-buckets/create-test-test.js b/ui/admin/tests/acceptance/storage-buckets/create-test.js similarity index 100% rename from ui/admin/tests/acceptance/storage-buckets/create-test-test.js rename to ui/admin/tests/acceptance/storage-buckets/create-test.js diff --git a/ui/admin/tests/acceptance/storage-buckets/read-test.js b/ui/admin/tests/acceptance/storage-buckets/read-test.js index f3f47c48c..b0aa243d9 100644 --- a/ui/admin/tests/acceptance/storage-buckets/read-test.js +++ b/ui/admin/tests/acceptance/storage-buckets/read-test.js @@ -16,6 +16,9 @@ module('Acceptance | storage-buckets | read', function (hooks) { let features; + const MESSAGE_SELECTOR = '.rose-message-subtitle'; + const TABLE_LINK_SELECTOR = '.hds-table__tbody tr:first-child a'; + const instances = { scopes: { global: null, @@ -27,6 +30,8 @@ module('Acceptance | storage-buckets | read', function (hooks) { const urls = { globalScope: null, storageBuckets: null, + storageBucket: null, + unknownStorageBucket: null, }; hooks.beforeEach(function () { @@ -40,19 +45,46 @@ module('Acceptance | storage-buckets | read', function (hooks) { }); urls.globalScope = `/scopes/global`; urls.storageBuckets = `${urls.globalScope}/storage-buckets`; + urls.storageBucket = `${urls.storageBuckets}/${instances.storageBucket.id}`; + urls.unknownStorageBucket = `${urls.storageBuckets}/foo`; features = this.owner.lookup('service:features'); features.enable('session-recording'); authenticateSession({}); }); - test('visiting storage buckets', async function (assert) { + test('visiting a storage bucket', async function (assert) { assert.expect(1); await visit(urls.globalScope); await a11yAudit(); await click(`[href="${urls.storageBuckets}"]`); + await a11yAudit(); + await click(`[href="${urls.storageBucket}"]`); + await a11yAudit(); - assert.strictEqual(currentURL(), urls.storageBuckets); + assert.strictEqual(currentURL(), urls.storageBucket); + }); + + test('cannot navigate to a storage bucket without proper authorization', async function (assert) { + assert.expect(1); + await visit(urls.globalScope); + instances.storageBucket.authorized_actions = + instances.storageBucket.authorized_actions.filter( + (item) => item !== 'read' + ); + + await click(`[href="${urls.storageBuckets}"]`); + + assert.dom(TABLE_LINK_SELECTOR).doesNotExist(); + }); + + test('visiting an unknown storage bucket displays 404 message', async function (assert) { + assert.expect(1); + + await visit(urls.unknownStorageBucket); + await a11yAudit(); + + assert.dom(MESSAGE_SELECTOR).hasText('Error 404'); }); }); diff --git a/ui/admin/tests/acceptance/storage-buckets/update-test.js b/ui/admin/tests/acceptance/storage-buckets/update-test.js index 8aa700854..b1f774839 100644 --- a/ui/admin/tests/acceptance/storage-buckets/update-test.js +++ b/ui/admin/tests/acceptance/storage-buckets/update-test.js @@ -1,5 +1,5 @@ import { module, test } from 'qunit'; -import { visit, click, fillIn } from '@ember/test-helpers'; +import { visit, click, fillIn, findAll } from '@ember/test-helpers'; import { setupApplicationTest } from 'ember-qunit'; import setupMirage from 'ember-cli-mirage/test-support/setup-mirage'; import { Response } from 'miragejs'; @@ -16,6 +16,19 @@ module('Acceptance | storage-buckets | update', function (hooks) { let features; + const BUTTON_SELECTOR = '.rose-form-actions [type="button"]'; + const SAVE_BUTTON_SELECTOR = '.rose-form-actions [type="submit"]'; + const NAME_FIELD_SELECTOR = '[name="name"]'; + const REGION_FIELD_SELECTOR = '[name="region"]'; + const ALERT_TEXT_SELECTOR = '[role="alert"] div'; + const FIELD_ERROR_TEXT_SELECTOR = '.hds-form-error__message'; + const SECRET_FIELD_BUTTON_SELECTOR = '.secret-input [type="button"]'; + const ACCESS_KEY_ID_FIELD_SELECTOR = '[name="access_key_id"]'; + const SECRET_ACCESS_KEY_FIELD_SELECTOR = '[name="secret_access_key"]'; + const NAME_FIELD_TEXT = 'Updated storage-bucket name'; + const ACCESS_KEY_ID_FIELD_TEXT = 'Updated access key id'; + const SECRET_ACCESS_KEY_FIELD_TEXT = 'Update secret access key'; + const instances = { scopes: { global: null, @@ -36,30 +49,97 @@ module('Acceptance | storage-buckets | update', function (hooks) { }); urls.globalScope = `/scopes/global`; urls.storageBuckets = `${urls.globalScope}/storage-buckets`; - (urls.storageBucket = `${urls.storageBuckets}/${instances.storageBucket.id}`), - (features = this.owner.lookup('service:features')); + urls.storageBucket = `${urls.storageBuckets}/${instances.storageBucket.id}`; + + features = this.owner.lookup('service:features'); features.enable('session-recording'); authenticateSession({}); }); test('can save changes to an existing storage-bucket', async function (assert) { - assert.expect(2); - await visit(urls.storageBucket); - await click('.rose-form-actions [type="button"]', 'Click edit mode'); - await fillIn('[name="name"]', 'Updated storage-bucket name'); - await click('.rose-form-actions [type="submit"]'); + assert.expect(3); + await visit(urls.storageBuckets); + + await click(`[href="${urls.storageBucket}"]`); + await click(BUTTON_SELECTOR, 'Click edit mode'); + await fillIn(NAME_FIELD_SELECTOR, NAME_FIELD_TEXT); + await click(SAVE_BUTTON_SELECTOR, 'Click save'); + assert.dom(`[href="${urls.storageBucket}"]`).isVisible(); - assert.dom('input[name="name"]').hasValue('Updated storage-bucket name'); + assert.dom(NAME_FIELD_SELECTOR).hasValue(NAME_FIELD_TEXT); + assert.strictEqual(instances.storageBucket.name, NAME_FIELD_TEXT); }); test('can cancel changes to an existing storage-bucket', async function (assert) { - assert.expect(1); + assert.expect(2); const name = instances.storageBucket.name; - await visit(urls.storageBucket); - await click('.rose-form-actions [type="button"]', 'Click edit mode'); - await fillIn('[name="name"]', 'Updated storage-bucket name'); - await click('.rose-form-actions [type="button"]'); - await assert.dom('input[name="name"]').hasValue(`${name}`); + await visit(urls.storageBuckets); + + await click(`[href="${urls.storageBucket}"]`); + await click(BUTTON_SELECTOR, 'Click edit mode'); + await fillIn(NAME_FIELD_SELECTOR, NAME_FIELD_TEXT); + await click(BUTTON_SELECTOR, 'Click cancel'); + + assert.dom(NAME_FIELD_SELECTOR).hasValue(`${name}`); + assert.strictEqual(instances.storageBucket.name, name); + }); + + test('can save changes to access key fields', async function (assert) { + assert.expect(8); + await visit(urls.storageBuckets); + + await click(`[href="${urls.storageBucket}"]`); + + assert.dom(SECRET_FIELD_BUTTON_SELECTOR).exists({ count: 2 }); + assert.dom(SECRET_FIELD_BUTTON_SELECTOR).isDisabled(); + + await click(BUTTON_SELECTOR, 'Click edit mode'); + + assert.dom(SECRET_FIELD_BUTTON_SELECTOR).isEnabled(); + assert.dom(SECRET_FIELD_BUTTON_SELECTOR).hasText('Edit'); + + await click(SECRET_FIELD_BUTTON_SELECTOR); + await click(findAll(SECRET_FIELD_BUTTON_SELECTOR)[1]); + + assert.dom(SECRET_FIELD_BUTTON_SELECTOR).hasText('Cancel'); + + await fillIn(ACCESS_KEY_ID_FIELD_SELECTOR, ACCESS_KEY_ID_FIELD_TEXT); + await fillIn( + SECRET_ACCESS_KEY_FIELD_SELECTOR, + SECRET_ACCESS_KEY_FIELD_TEXT + ); + await click(SAVE_BUTTON_SELECTOR, 'Click save'); + + assert.dom(SECRET_FIELD_BUTTON_SELECTOR).isDisabled(); + assert.dom(ACCESS_KEY_ID_FIELD_SELECTOR).hasValue(ACCESS_KEY_ID_FIELD_TEXT); + assert + .dom(SECRET_ACCESS_KEY_FIELD_SELECTOR) + .hasValue(SECRET_ACCESS_KEY_FIELD_TEXT); + }); + + test('can cancel changes to access key fields', async function (assert) { + assert.expect(3); + await visit(urls.storageBuckets); + + await click(`[href="${urls.storageBucket}"]`); + await click(BUTTON_SELECTOR, 'Click edit mode'); + await click(SECRET_FIELD_BUTTON_SELECTOR, 'Click edit button'); + await click(findAll(SECRET_FIELD_BUTTON_SELECTOR)[1], 'Click edit button'); + await fillIn(ACCESS_KEY_ID_FIELD_SELECTOR, ACCESS_KEY_ID_FIELD_TEXT); + await fillIn( + SECRET_ACCESS_KEY_FIELD_SELECTOR, + SECRET_ACCESS_KEY_FIELD_TEXT + ); + await click(SECRET_FIELD_BUTTON_SELECTOR, 'Click cancel button'); + await click( + findAll(SECRET_FIELD_BUTTON_SELECTOR)[1], + 'Click cancel button' + ); + await click(SAVE_BUTTON_SELECTOR, 'Click save'); + + assert.dom(SECRET_FIELD_BUTTON_SELECTOR).isDisabled(); + assert.dom(ACCESS_KEY_ID_FIELD_SELECTOR).hasNoValue(); + assert.dom(SECRET_ACCESS_KEY_FIELD_SELECTOR).hasNoValue(); }); test('saving an existing storage-bucket with invalid fields will display error messages', async function (assert) { @@ -86,11 +166,11 @@ module('Acceptance | storage-buckets | update', function (hooks) { }); await click(`[href="${urls.storageBucket}"]`); - await click('.rose-form-actions [type="button"]', 'Activate edit mode'); - await fillIn('[name="region"]', 'random string'); - await click('[type="submit"]'); + await click(BUTTON_SELECTOR, 'Activate edit mode'); + await fillIn(REGION_FIELD_SELECTOR, 'random string'); + await click(SAVE_BUTTON_SELECTOR); - assert.dom('[role="alert"] div').hasText('The request was invalid.'); - assert.dom('.hds-form-error__message').hasText('Region is required.'); + assert.dom(ALERT_TEXT_SELECTOR).hasText('The request was invalid.'); + assert.dom(FIELD_ERROR_TEXT_SELECTOR).hasText('Region is required.'); }); }); From 1f581fcc759f94335e96aa832b74e33ac499a9d6 Mon Sep 17 00:00:00 2001 From: Zhihe Li Date: Tue, 28 Mar 2023 12:08:15 -0400 Subject: [PATCH 092/193] =?UTF-8?q?chore:=20=F0=9F=A4=96=20Remove=20type?= =?UTF-8?q?=20on=20channel=20recordings=20(#155)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../generated/models/channel-recording.js | 6 ----- addons/api/addon/models/channel-recording.js | 21 --------------- .../api/mirage/factories/channel-recording.js | 2 -- .../unit/models/channel-recording-test.js | 27 ------------------- 4 files changed, 56 deletions(-) diff --git a/addons/api/addon/generated/models/channel-recording.js b/addons/api/addon/generated/models/channel-recording.js index 77f5dbc5c..fe2d7bbb0 100644 --- a/addons/api/addon/generated/models/channel-recording.js +++ b/addons/api/addon/generated/models/channel-recording.js @@ -12,12 +12,6 @@ import { attr } from '@ember-data/model'; export default class GeneratedChannelRecordingModel extends BaseModel { // =attributes - @attr('string', { - description: 'The type of the resource, to help differentiate schemas', - readOnly: true, - }) - type; - @attr('number', { description: 'The total number of bytes uploaded from the client in this Channel.', diff --git a/addons/api/addon/models/channel-recording.js b/addons/api/addon/models/channel-recording.js index 42c459170..993a5d69b 100644 --- a/addons/api/addon/models/channel-recording.js +++ b/addons/api/addon/models/channel-recording.js @@ -1,30 +1,9 @@ import GeneratedChannelRecordingModel from '../generated/models/channel-recording'; import { belongsTo } from '@ember-data/model'; -export const TYPE_CHANNEL_RECORDING_SESSION = 'session'; -export const TYPES_CHANNEL_RECORDING = Object.freeze([ - TYPE_CHANNEL_RECORDING_SESSION, -]); - export default class ChannelRecordingModel extends GeneratedChannelRecordingModel { @belongsTo('connection-recording') connection_recording; - /** - * True if the channel type is `session`. - * @type {boolean} - */ - get isSession() { - return this.type === TYPE_CHANNEL_RECORDING_SESSION; - } - - /** - * True if the channel is an unknown type. - * @type {boolean} - */ - get isUnknown() { - return !TYPES_CHANNEL_RECORDING.includes(this.type); - } - /** * Download the ascii cast recording for this channel. * @returns {Promise} diff --git a/addons/api/mirage/factories/channel-recording.js b/addons/api/mirage/factories/channel-recording.js index 685b08115..ecc72d2ec 100644 --- a/addons/api/mirage/factories/channel-recording.js +++ b/addons/api/mirage/factories/channel-recording.js @@ -5,9 +5,7 @@ import factory from '../generated/factories/channel-recording'; import generateId from '../helpers/id'; -import { TYPES_CHANNEL_RECORDING as types } from 'api/models/channel-recording'; export default factory.extend({ id: () => generateId('chr_'), - type: (i) => types[i % types.length], }); diff --git a/addons/api/tests/unit/models/channel-recording-test.js b/addons/api/tests/unit/models/channel-recording-test.js index 0a73c18d0..2ec3d2427 100644 --- a/addons/api/tests/unit/models/channel-recording-test.js +++ b/addons/api/tests/unit/models/channel-recording-test.js @@ -1,6 +1,5 @@ import { module, test } from 'qunit'; import { setupTest } from 'ember-qunit'; -import { TYPE_CHANNEL_RECORDING_SESSION } from 'api/models/channel-recording'; module('Unit | Model | channel-recording', function (hooks) { setupTest(hooks); @@ -10,30 +9,4 @@ module('Unit | Model | channel-recording', function (hooks) { let model = store.createRecord('channel-recording', {}); assert.ok(model); }); - - test('it has isUnknown property and returns the expected values', async function (assert) { - assert.expect(2); - const store = this.owner.lookup('service:store'); - const modelA = store.createRecord('channel-recording', { - type: TYPE_CHANNEL_RECORDING_SESSION, - }); - const modelB = store.createRecord('channel-recording', { - type: 'no-such-type', - }); - assert.false(modelA.isUnknown); - assert.true(modelB.isUnknown); - }); - - test('it has isSession property and returns the expected values', async function (assert) { - assert.expect(2); - const store = this.owner.lookup('service:store'); - const modelA = store.createRecord('channel-recording', { - type: TYPE_CHANNEL_RECORDING_SESSION, - }); - const modelB = store.createRecord('channel-recording', { - type: 'random', - }); - assert.true(modelA.isSession); - assert.false(modelB.isSession); - }); }); From 992be8c4fb064f3a8fca22f51475cd123e2c3cfd Mon Sep 17 00:00:00 2001 From: Cameron Perera Date: Tue, 28 Mar 2023 11:25:50 -0500 Subject: [PATCH 093/193] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20add=20sidebar=20?= =?UTF-8?q?data=20for=20session=20recording=20screen=20(#158)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 🎸 add sidebar data for session recording screen βœ… Closes: ICU-8610 * refactor: πŸ’‘ add logic for no storage bucket linked to target * refactor: πŸ’‘ update comments --- addons/core/translations/resources/en-us.yaml | 2 + .../session-recordings/session-recording.js | 22 +++++++- .../session-recording/index.hbs | 50 ++++++++++++++++++- 3 files changed, 71 insertions(+), 3 deletions(-) diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml index 3debadfdc..84c878b90 100644 --- a/addons/core/translations/resources/en-us.yaml +++ b/addons/core/translations/resources/en-us.yaml @@ -214,6 +214,8 @@ org: session-recording: title: Session Recording title_plural: Session Recordings + details: Session details + related: Related connection: title: Connection title_plural: Connections diff --git a/ui/admin/app/routes/scopes/scope/session-recordings/session-recording.js b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording.js index 47ae85ee4..b4d2e2f43 100644 --- a/ui/admin/app/routes/scopes/scope/session-recordings/session-recording.js +++ b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording.js @@ -16,7 +16,27 @@ export default class ScopesScopeSessionRecordingsSessionRecordingRoute extends R if (!this.session.isAuthenticated) this.router.transitionTo('index'); } + /** + * Load session recording and related storage bucket if present + * @return {SessionRecordingModel, ?StorageBucketModel} + */ async model({ session_recording_id }) { - return this.store.findRecord('session-recording', session_recording_id); + let storageBucket = null; + const sessionRecording = await this.store.findRecord( + 'session-recording', + session_recording_id + ); + if (sessionRecording.target?.storage_bucket_id) { + const { storage_bucket_id } = sessionRecording.target; + storageBucket = await this.store.findRecord( + 'storage-bucket', + storage_bucket_id + ); + } + + return { + sessionRecording, + storageBucket, + }; } } diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs index 5c89e63a4..dac6007af 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs @@ -11,7 +11,10 @@
- {{#each @model.connection_recordings as |connection|}} + {{#each + @model.sessionRecording.connection_recordings + as |connection| + }}

{{t 'resources.session-recording.connection.title'}} @@ -77,7 +80,50 @@ {{/each}} -

{{t 'actions.help'}}

+
+

{{t 'resources.session-recording.details'}}

+ {{! Start time }} +

+ + {{@model.sessionRecording.start_time}} +

+ {{! Duration }} +

+ + {{@model.sessionRecording.duration}} +

+ + {{! Bytes up }} +

+ + {{@model.sessionRecording.bytes_up}} +

+ + {{! Bytes down }} +

+ + {{@model.sessionRecording.bytes_down}} +

+
+ {{! Related }} +
+

{{t 'resources.session-recording.related'}}

+ {{! User name }} +

+ + {{@model.sessionRecording.user.name}} +

+ {{! Target name }} +

+ + {{@model.sessionRecording.target.name}} +

+ {{! Bucket name }} +

+ + {{@model.storageBucket.name}} +

+
From 502f04d02a46cbcaaf366ac692c990f4bb25c5cf Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Corvo Date: Tue, 28 Mar 2023 09:48:22 -0700 Subject: [PATCH 094/193] =?UTF-8?q?refactor:=20=F0=9F=92=A1=20Add=20Projec?= =?UTF-8?q?t=20name=20to=20session-recordings=20list=20(#152)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: πŸ’‘ Add Project name to session-recordings list --- addons/api/addon/models/session-recording.js | 4 +++ .../unit/models/session-recording-test.js | 34 +++++++++++++++++++ .../scopes/scope/session-recordings/index.hbs | 7 ++++ .../session-recordings/list-test.js | 5 ++- 4 files changed, 49 insertions(+), 1 deletion(-) diff --git a/addons/api/addon/models/session-recording.js b/addons/api/addon/models/session-recording.js index db0714b51..89ee6560d 100644 --- a/addons/api/addon/models/session-recording.js +++ b/addons/api/addon/models/session-recording.js @@ -27,4 +27,8 @@ export default class SessionRecordingModel extends GeneratedSessionRecordingMode get isUnknown() { return !TYPES_SESSION_RECORDING.includes(this.type); } + + get targetScopeDisplayName() { + return this.target?.scope?.name || this.target?.scope?.id; + } } diff --git a/addons/api/tests/unit/models/session-recording-test.js b/addons/api/tests/unit/models/session-recording-test.js index ca6705d00..af61282a6 100644 --- a/addons/api/tests/unit/models/session-recording-test.js +++ b/addons/api/tests/unit/models/session-recording-test.js @@ -50,4 +50,38 @@ module('Unit | Model | session-recording', function (hooks) { const connection_recordings = await model.connection_recordings; assert.strictEqual(connection_recordings.length, 1); }); + + test('it has targetScopeDisplayName and returns the expected values', async function (assert) { + assert.expect(2); + const store = this.owner.lookup('service:store'); + const fakeName = 'Scope name'; + const fakeId = 's_123456789'; + // Scope models: A has just name, B has just id. + const scopeModelA = await store.createRecord('scope', { + type: 'global', + name: fakeName, + id: 's_1234567890', + }); + const scopeModelB = await store.createRecord('scope', { + type: 'org', + id: fakeId, + }); + + const targetModelA = await store.createRecord('target', { + scope: scopeModelA, + }); + const targetModelB = await store.createRecord('target', { + scope: scopeModelB, + }); + + const modelA = store.createRecord('session-recording', { + target: targetModelA, + }); + const modelB = store.createRecord('session-recording', { + target: targetModelB, + }); + + assert.strictEqual(modelA.targetScopeDisplayName, fakeName); + assert.strictEqual(modelB.targetScopeDisplayName, fakeId); + }); }); diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs index 10f3bafb0..fd82545f3 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs @@ -22,11 +22,13 @@ > <:body as |B|> + {{! Time }} {{format-date B.data.start_time format='mmddyyhhmm'}} + {{! User }}
{{B.data.user.name}}
+ {{! Target }}
+ + {{B.data.targetScopeDisplayName}} + / {{B.data.target.name}}
+ {{! Duration }}
Date: Tue, 28 Mar 2023 14:22:12 -0500 Subject: [PATCH 095/193] =?UTF-8?q?refactor:=20=F0=9F=92=A1=20show=20"Stor?= =?UTF-8?q?age=20Bucket"=20on=20session=20recording=20screen=20(#160)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: πŸ’‘ show "Storage Bucket" on session recording screen if no storage bucket found * Update ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs Co-authored-by: Randall Morey * refactor: πŸ’‘ fix lint issue --------- Co-authored-by: Randall Morey --- .../scope/session-recordings/session-recording/index.hbs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs index dac6007af..2731de566 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs @@ -121,7 +121,10 @@ {{! Bucket name }}

- {{@model.storageBucket.name}} + {{or + @model.storageBucket.name + (t 'resources.storage-bucket.title') + }}

From 3693ee88c097af750416ad806871f14f764fd2e5 Mon Sep 17 00:00:00 2001 From: Zhihe Li Date: Tue, 28 Mar 2023 16:20:40 -0400 Subject: [PATCH 096/193] =?UTF-8?q?refactor:=20=F0=9F=92=A1=20Change=20byt?= =?UTF-8?q?es=20to=20be=20strings=20(#161)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- addons/api/addon/generated/models/channel-recording.js | 4 ++-- addons/api/addon/generated/models/connection-recording.js | 4 ++-- addons/api/addon/generated/models/session-recording.js | 4 ++-- addons/api/mirage/generated/factories/channel-recording.js | 6 ++++-- .../api/mirage/generated/factories/connection-recording.js | 6 ++++-- addons/api/mirage/generated/factories/session-recording.js | 6 ++++-- 6 files changed, 18 insertions(+), 12 deletions(-) diff --git a/addons/api/addon/generated/models/channel-recording.js b/addons/api/addon/generated/models/channel-recording.js index fe2d7bbb0..18a29db9d 100644 --- a/addons/api/addon/generated/models/channel-recording.js +++ b/addons/api/addon/generated/models/channel-recording.js @@ -12,14 +12,14 @@ import { attr } from '@ember-data/model'; export default class GeneratedChannelRecordingModel extends BaseModel { // =attributes - @attr('number', { + @attr('string', { description: 'The total number of bytes uploaded from the client in this Channel.', readOnly: true, }) bytes_up; - @attr('number', { + @attr('string', { description: 'The total number of bytes downloaded to the client in this Channel.', readOnly: true, diff --git a/addons/api/addon/generated/models/connection-recording.js b/addons/api/addon/generated/models/connection-recording.js index 66688e07d..bb015f7c5 100644 --- a/addons/api/addon/generated/models/connection-recording.js +++ b/addons/api/addon/generated/models/connection-recording.js @@ -19,14 +19,14 @@ export default class GeneratedConnectionRecordingModel extends BaseModel { }) connection_id; - @attr('number', { + @attr('string', { description: 'The total number of bytes uploaded from the client in this Connection.', readOnly: true, }) bytes_up; - @attr('number', { + @attr('string', { description: 'The total number of bytes downloaded to the client in this Connection.', readOnly: true, diff --git a/addons/api/addon/generated/models/session-recording.js b/addons/api/addon/generated/models/session-recording.js index 1b544406b..f8d3b7930 100644 --- a/addons/api/addon/generated/models/session-recording.js +++ b/addons/api/addon/generated/models/session-recording.js @@ -36,14 +36,14 @@ export default class GeneratedSessionRecordingModel extends BaseModel { }) session_id; - @attr('number', { + @attr('string', { description: 'The total number of bytes uploaded from the client in the Session.', readOnly: true, }) bytes_up; - @attr('number', { + @attr('string', { description: 'The total number of bytes downloaded to the client in the Session.', readOnly: true, diff --git a/addons/api/mirage/generated/factories/channel-recording.js b/addons/api/mirage/generated/factories/channel-recording.js index 7e3ee6c47..58980d2c2 100644 --- a/addons/api/mirage/generated/factories/channel-recording.js +++ b/addons/api/mirage/generated/factories/channel-recording.js @@ -10,8 +10,10 @@ import { faker } from '@faker-js/faker'; * GeneratedChannelRecordingModelFactory */ export default Factory.extend({ - bytes_up: () => faker.datatype.number(), - bytes_down: () => faker.datatype.number(), + bytes_up: () => + faker.random.numeric(faker.datatype.number({ min: 1, max: 12 })), + bytes_down: () => + faker.random.numeric(faker.datatype.number({ min: 1, max: 12 })), errors: () => faker.datatype.number({ max: 10 }), start_time() { return faker.date.recent(3, this.end_time); diff --git a/addons/api/mirage/generated/factories/connection-recording.js b/addons/api/mirage/generated/factories/connection-recording.js index 943b47533..e36f7b262 100644 --- a/addons/api/mirage/generated/factories/connection-recording.js +++ b/addons/api/mirage/generated/factories/connection-recording.js @@ -10,8 +10,10 @@ import { faker } from '@faker-js/faker'; * GeneratedConnectionRecordingModelFactory */ export default Factory.extend({ - bytes_up: () => faker.datatype.number(), - bytes_down: () => faker.datatype.number(), + bytes_up: () => + faker.random.numeric(faker.datatype.number({ min: 1, max: 12 })), + bytes_down: () => + faker.random.numeric(faker.datatype.number({ min: 1, max: 12 })), errors: () => faker.datatype.number({ max: 10 }), start_time() { return faker.date.recent(3, this.end_time); diff --git a/addons/api/mirage/generated/factories/session-recording.js b/addons/api/mirage/generated/factories/session-recording.js index 379d671c1..19ebb4650 100644 --- a/addons/api/mirage/generated/factories/session-recording.js +++ b/addons/api/mirage/generated/factories/session-recording.js @@ -10,8 +10,10 @@ import { faker } from '@faker-js/faker'; * GeneratedSessionRecordingModelFactory */ export default Factory.extend({ - bytes_up: () => faker.datatype.number(), - bytes_down: () => faker.datatype.number(), + bytes_up: () => + faker.random.numeric(faker.datatype.number({ min: 1, max: 12 })), + bytes_down: () => + faker.random.numeric(faker.datatype.number({ min: 1, max: 12 })), errors: () => faker.datatype.number({ max: 10 }), start_time() { return faker.date.recent(3, this.end_time); From 63c573964fa5a2b447d29c4619cd87de48fe047d Mon Sep 17 00:00:00 2001 From: Cameron Perera Date: Wed, 29 Mar 2023 12:30:05 -0500 Subject: [PATCH 097/193] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20add=20permission?= =?UTF-8?q?s=20check=20for=20session=20recording=20navigation=20(#164)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ui/admin/app/abilities/session-recording.js | 3 +- ui/admin/app/templates/scopes/scope.hbs | 16 ++++++-- .../session-recordings/list-test.js | 38 +++++++++++++++++-- 3 files changed, 48 insertions(+), 9 deletions(-) diff --git a/ui/admin/app/abilities/session-recording.js b/ui/admin/app/abilities/session-recording.js index ed0a53499..346c97dcd 100644 --- a/ui/admin/app/abilities/session-recording.js +++ b/ui/admin/app/abilities/session-recording.js @@ -20,7 +20,8 @@ export default class OverrideSessionRecordingAbility extends SessionRecordingAbi /** * This override ensures that session recordings can only be presented in the global scope - * and if the session-recording feature flag is enabled. */ + * and if the session-recording feature flag is enabled. + */ get canList() { return this.features.isEnabled('session-recording') ? this.hasAuthorizedCollectionAction('list') && this.model.isGlobal diff --git a/ui/admin/app/templates/scopes/scope.hbs b/ui/admin/app/templates/scopes/scope.hbs index 67694f447..64feeb900 100644 --- a/ui/admin/app/templates/scopes/scope.hbs +++ b/ui/admin/app/templates/scopes/scope.hbs @@ -27,10 +27,18 @@ {{t 'resources.org.title_plural'}} {{#if (feature-flag 'session-recording')}} - - - {{t 'resources.session-recording.title_plural'}} - + {{#if + (can + 'navigate session-recording' + @model + collection='session-recordings' + ) + }} + + + {{t 'resources.session-recording.title_plural'}} + + {{/if}} {{#if (can 'navigate storage-bucket' @model collection='storage-buckets' diff --git a/ui/admin/tests/acceptance/session-recordings/list-test.js b/ui/admin/tests/acceptance/session-recordings/list-test.js index f86374f8c..2c7587008 100644 --- a/ui/admin/tests/acceptance/session-recordings/list-test.js +++ b/ui/admin/tests/acceptance/session-recordings/list-test.js @@ -3,6 +3,7 @@ import { visit, currentURL, click } from '@ember/test-helpers'; import { setupApplicationTest } from 'admin/tests/helpers'; import setupMirage from 'ember-cli-mirage/test-support/setup-mirage'; import { authenticateSession } from 'ember-simple-auth/test-support'; +import { enableFeature } from 'ember-feature-flags/test-support'; module('Acceptance | session recordings | list', function (hooks) { setupApplicationTest(hooks); @@ -11,6 +12,7 @@ module('Acceptance | session recordings | list', function (hooks) { // Selectors const LIST_SESSION_RECORDING_BUTTON = 'table > tbody > tr > td:last-child > a'; + const SESSION_RECORDING_TITLE = 'Session Recordings'; // Instances const instances = { @@ -43,17 +45,45 @@ module('Acceptance | session recordings | list', function (hooks) { urls.globalScope = `/scopes/global`; urls.sessionRecordings = `${urls.globalScope}/session-recordings`; urls.sessionRecording = `${urls.sessionRecordings}/${instances.sessionRecording.id}`; + enableFeature('session-recording'); authenticateSession({}); }); - // TODO: When we add abilities to session-recordings this test will be refactor to account for it. - test('users can navigate to session-recordings', async function (assert) { - assert.expect(1); + test('users can navigate to session-recordings with proper authorization', async function (assert) { + assert.expect(4); + + await visit(urls.globalScope); + + assert.true( + instances.scopes.global.authorized_collection_actions[ + 'session-recordings' + ].includes('list') + ); + assert.dom(`[href="${urls.sessionRecordings}"]`).exists(); + assert.dom('[title="General"]').includesText(SESSION_RECORDING_TITLE); + // Visit session recordings - await visit(urls.sessionRecordings); + await click(`[href="${urls.sessionRecordings}"]`); assert.strictEqual(currentURL(), urls.sessionRecordings); }); + test('users cannot navigate to session-recordings without the list action', async function (assert) { + assert.expect(3); + instances.scopes.global.authorized_collection_actions[ + 'session-recordings' + ] = []; + + await visit(urls.globalScope); + + assert.false( + instances.scopes.global.authorized_collection_actions[ + 'session-recordings' + ].includes('list') + ); + assert.dom('[title="General"]').doesNotIncludeText(SESSION_RECORDING_TITLE); + assert.dom(`[href="${urls.sessionRecordings}"]`).doesNotExist(); + }); + // TODO: When we add abilities to session-recordings this test will be refactor to account for it. test('user can navigate to a session recording', async function (assert) { assert.expect(2); From 60de33598a97d5d21fda2c55e299325bf9364c8e Mon Sep 17 00:00:00 2001 From: Devon Anderson Date: Wed, 29 Mar 2023 15:45:40 -0400 Subject: [PATCH 098/193] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20create=20enable-?= =?UTF-8?q?session-recording=20view=20(#165)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 🎸 create enable-session-recording view Create `enable-session-recording` ui view. βœ… Closes: ICU-8592 * refactor: πŸ’‘ refactor scss for enable-session-recording Refactor scss to use `rem` instead of Rose mixins for sizing. βœ… Closes: ICU-8592 * refactor: πŸ’‘ removed integration test Removed integration test for `form/enable-session-recording`. User testing will come from targets acceptance test. βœ… Closes: ICU-8592 --- addons/core/translations/resources/en-us.yaml | 14 ++++ .../form/enable-session-recording/index.hbs | 68 +++++++++++++++++++ .../form/enable-session-recording/index.js | 7 ++ .../target/enable-session-recording.js | 18 +++++ .../target/enable-session-recording.js | 19 +++++- ui/admin/app/styles/app.scss | 15 ++++ .../target/enable-session-recording.hbs | 30 +++++++- ui/admin/config/environment.js | 1 + .../target/enable-session-recording-test.js | 17 +++++ 9 files changed, 187 insertions(+), 2 deletions(-) create mode 100644 ui/admin/app/components/form/enable-session-recording/index.hbs create mode 100644 ui/admin/app/components/form/enable-session-recording/index.js create mode 100644 ui/admin/app/controllers/scopes/scope/targets/target/enable-session-recording.js create mode 100644 ui/admin/tests/unit/controllers/scopes/scope/targets/target/enable-session-recording-test.js diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml index 84c878b90..680e5c0fa 100644 --- a/addons/core/translations/resources/en-us.yaml +++ b/addons/core/translations/resources/en-us.yaml @@ -427,6 +427,20 @@ target: delete-address: title: Remove target address? message: This target has an assigned address. Adding a host source will remove the assigned address from the target when you save your changes. + enable-session-recording: + title: Enable Session Recording + messages: + add: + title: Enable session recording for target + options: + 1: Storage Bucket 1 + 2: Storage Bucket 2 + form: + filter: + label: Record sessions for this target + select: + label: AWS storage buckets + description: Description for storage buckets brokered-credential-source: title: Brokered Credential title_plural: Brokered Credentials diff --git a/ui/admin/app/components/form/enable-session-recording/index.hbs b/ui/admin/app/components/form/enable-session-recording/index.hbs new file mode 100644 index 000000000..5b60064a4 --- /dev/null +++ b/ui/admin/app/components/form/enable-session-recording/index.hbs @@ -0,0 +1,68 @@ + +
+ + + {{t + 'resources.target.enable-session-recording.form.filter.label' + }} + + + {{#if this.toggleEnabled}} + + {{t + 'resources.target.enable-session-recording.form.select.label' + }} + + {{!TODO: add correct description for form-select}} + + {{t + 'resources.target.enable-session-recording.form.select.description' + }} + + + {{!TODO: replace dummy data with storage-bucket name and remove uneeded translations}} + + + + + + {{#if @model.errors.name}} + + {{#each @model.errors.name as |error|}} + {{error.message}} + {{/each}} + + {{/if}} + + {{/if}} + + + + +
+
\ No newline at end of file diff --git a/ui/admin/app/components/form/enable-session-recording/index.js b/ui/admin/app/components/form/enable-session-recording/index.js new file mode 100644 index 000000000..2ad3f2629 --- /dev/null +++ b/ui/admin/app/components/form/enable-session-recording/index.js @@ -0,0 +1,7 @@ +import Component from '@glimmer/component'; +import { tracked } from '@glimmer/tracking'; + +export default class FormEnableSessionRecordingIndexComponent extends Component { + // =attributes + @tracked toggleEnabled = true; +} diff --git a/ui/admin/app/controllers/scopes/scope/targets/target/enable-session-recording.js b/ui/admin/app/controllers/scopes/scope/targets/target/enable-session-recording.js new file mode 100644 index 000000000..1af8f7f7d --- /dev/null +++ b/ui/admin/app/controllers/scopes/scope/targets/target/enable-session-recording.js @@ -0,0 +1,18 @@ +import Controller from '@ember/controller'; +import { inject as service } from '@ember/service'; + +export default class ScopesScopeTargetsTargetEnableSessionRecordingController extends Controller { + // =services + + @service intl; + + // =attributes + + /** + * Translated enable session recording breadcrumb + * @type {string} + */ + get breadCrumb() { + return this.intl.t('resources.target.enable-session-recording.title'); + } +} diff --git a/ui/admin/app/routes/scopes/scope/targets/target/enable-session-recording.js b/ui/admin/app/routes/scopes/scope/targets/target/enable-session-recording.js index d6dd6e257..5dd07dd22 100644 --- a/ui/admin/app/routes/scopes/scope/targets/target/enable-session-recording.js +++ b/ui/admin/app/routes/scopes/scope/targets/target/enable-session-recording.js @@ -1,3 +1,20 @@ import Route from '@ember/routing/route'; +import { inject as service } from '@ember/service'; -export default class ScopesScopeTargetsTargetEnableSessionRecordingRoute extends Route {} +export default class ScopesScopeTargetsTargetEnableSessionRecordingRoute extends Route { + // =services + + @service router; + + // =methods + + /** + * Returns the current target and all storage buckets. + * @return {{target: TargetModel, storageBuckets: [StorageBucketModel]}} + */ + + async model() { + // TODO: need model for storage_bucket as well + return this.modelFor('scopes.scope.targets.target'); + } +} diff --git a/ui/admin/app/styles/app.scss b/ui/admin/app/styles/app.scss index 4131c3e5b..99cf43f94 100644 --- a/ui/admin/app/styles/app.scss +++ b/ui/admin/app/styles/app.scss @@ -643,6 +643,21 @@ } } +.enable-session-recording-toggle { + width: 50%; + margin-top: 1.5rem; + + .hds-form-field--layout-vertical, + .hds-link-standalone { + margin-left: 2.5rem; + } + + .hds-link-standalone { + margin-top: 0.75rem; + margin-bottom: 1.5rem; + } +} + // target sidebar .target-sidebar { .title-wrapper { diff --git a/ui/admin/app/templates/scopes/scope/targets/target/enable-session-recording.hbs b/ui/admin/app/templates/scopes/scope/targets/target/enable-session-recording.hbs index 559ab26d4..81e7bad08 100644 --- a/ui/admin/app/templates/scopes/scope/targets/target/enable-session-recording.hbs +++ b/ui/admin/app/templates/scopes/scope/targets/target/enable-session-recording.hbs @@ -1,2 +1,30 @@ {{page-title (t 'resources.target.actions.enable-session-recording')}} -{{outlet}} \ No newline at end of file + + + + + + + +

{{t 'resources.target.enable-session-recording.messages.add.title'}} + +

+ {{!TODO: add description for enabling session recording}} + + {{@model.id}} + +
+ + + + + +
\ No newline at end of file diff --git a/ui/admin/config/environment.js b/ui/admin/config/environment.js index 21063d367..a6fb109fb 100644 --- a/ui/admin/config/environment.js +++ b/ui/admin/config/environment.js @@ -78,6 +78,7 @@ module.exports = function (environment) { target: '/targets', 'target.new': '/targets/new', 'target.add-host-sources': '/targets/add-host-sets', + 'target.enable-session-recording': '/targets/enable-session-recording', 'target.worker-filters': '/targets/worker-filters', user: '/users', downloads: '/downloads', diff --git a/ui/admin/tests/unit/controllers/scopes/scope/targets/target/enable-session-recording-test.js b/ui/admin/tests/unit/controllers/scopes/scope/targets/target/enable-session-recording-test.js new file mode 100644 index 000000000..0aca32f5b --- /dev/null +++ b/ui/admin/tests/unit/controllers/scopes/scope/targets/target/enable-session-recording-test.js @@ -0,0 +1,17 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'admin/tests/helpers'; + +module( + 'Unit | Controller | scopes/scope/targets/target/enable-session-recording', + function (hooks) { + setupTest(hooks); + + // TODO: Replace this with your real tests. + test('it exists', function (assert) { + let controller = this.owner.lookup( + 'controller:scopes/scope/targets/target/enable-session-recording' + ); + assert.ok(controller); + }); + } +); From ae66e68bad66d92e0b41a3c1367711e03f230166 Mon Sep 17 00:00:00 2001 From: Devon Anderson Date: Thu, 30 Mar 2023 08:29:52 -0400 Subject: [PATCH 099/193] =?UTF-8?q?chore:=20=F0=9F=A4=96=20add=20related?= =?UTF-8?q?=20test=20for=20target=20sidebar=20(#166)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: πŸ€– add related test for target sidebar Add related acceptance test for `session-recording` sidebar integration into `target` form. βœ… Closes: ICU-8590 * Update read-test.js * refactor: πŸ’‘ fix test Fix failing test for sidebar component. * Update ui/admin/tests/acceptance/targets/read-test.js Co-authored-by: Zhihe Li * Update ui/admin/tests/acceptance/targets/read-test.js Co-authored-by: Zhihe Li --------- Co-authored-by: Zhihe Li --- .../tests/acceptance/targets/read-test.js | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/ui/admin/tests/acceptance/targets/read-test.js b/ui/admin/tests/acceptance/targets/read-test.js index e6205e150..76c054a0d 100644 --- a/ui/admin/tests/acceptance/targets/read-test.js +++ b/ui/admin/tests/acceptance/targets/read-test.js @@ -38,6 +38,7 @@ module('Acceptance | targets | read', function (hooks) { targets: null, sshTarget: null, tcpTarget: null, + enableSessionRecording: null, }; hooks.beforeEach(function () { @@ -68,6 +69,7 @@ module('Acceptance | targets | read', function (hooks) { urls.sshTarget = `${urls.targets}/${instances.sshTarget.id}`; urls.tcpTarget = `${urls.targets}/${instances.tcpTarget.id}`; urls.unknownTarget = `${urls.targets}/foo`; + urls.enableSessionRecording = `${urls.sshTarget}/enable-session-recording`; authenticateSession({}); }); @@ -190,4 +192,22 @@ module('Acceptance | targets | read', function (hooks) { .dom(`[href="https://boundaryproject.io/help/admin-ui/targets"]`) .exists(); }); + + test('users can click on enable-recording button in target session-recording sidebar and it takes them to enable session recording', async function (assert) { + assert.expect(1); + + await visit(urls.sshTarget); + + await click('.target-sidebar a'); + assert.strictEqual(currentURL(), urls.enableSessionRecording); + }); + + test('users can click on settings icon in target session-recording sidebar and it takes them to enable session recording', async function (assert) { + assert.expect(1); + + await visit(urls.sshTarget); + + await click('.target-sidebar .title-wrapper a'); + assert.strictEqual(currentURL(), urls.enableSessionRecording); + }); }); From 7faab01452eea49d46fe11135f529fbbaa2b3b69 Mon Sep 17 00:00:00 2001 From: Cameron Perera Date: Thu, 30 Mar 2023 11:11:40 -0500 Subject: [PATCH 100/193] =?UTF-8?q?refactor:=20=F0=9F=92=A1=20add=20permis?= =?UTF-8?q?sion=20to=20read=20a=20session=20recording=20(#167)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: πŸ’‘ add permission to read a session recording * test: πŸ’ remove a11yAudit from test temporarily * refactor: πŸ’‘ add aria-label to fix allyAudit violation (#168) * refactor: πŸ’‘ add aria-label to fix allyAudit violation * refactor: πŸ’‘ update standalone link to icon only button --- addons/core/translations/resources/en-us.yaml | 1 + .../scopes/scope/session-recordings/index.hbs | 21 ++++++---- .../session-recordings/list-test.js | 13 ------ ...session-recording-test.js => read-test.js} | 40 +++++++++++++++++-- 4 files changed, 50 insertions(+), 25 deletions(-) rename ui/admin/tests/acceptance/session-recordings/{session-recording/session-recording-test.js => read-test.js} (60%) diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml index 680e5c0fa..010d964b8 100644 --- a/addons/core/translations/resources/en-us.yaml +++ b/addons/core/translations/resources/en-us.yaml @@ -216,6 +216,7 @@ session-recording: title_plural: Session Recordings details: Session details related: Related + button-aria-label: Go to session recording {id} connection: title: Connection title_plural: Connections diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs index fd82545f3..95333b716 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs @@ -61,14 +61,19 @@
- + {{#if (can 'read session-recording' B.data)}} + + {{/if}} diff --git a/ui/admin/tests/acceptance/session-recordings/list-test.js b/ui/admin/tests/acceptance/session-recordings/list-test.js index 2c7587008..acd15f203 100644 --- a/ui/admin/tests/acceptance/session-recordings/list-test.js +++ b/ui/admin/tests/acceptance/session-recordings/list-test.js @@ -10,8 +10,6 @@ module('Acceptance | session recordings | list', function (hooks) { setupMirage(hooks); // Selectors - const LIST_SESSION_RECORDING_BUTTON = - 'table > tbody > tr > td:last-child > a'; const SESSION_RECORDING_TITLE = 'Session Recordings'; // Instances @@ -83,15 +81,4 @@ module('Acceptance | session recordings | list', function (hooks) { assert.dom('[title="General"]').doesNotIncludeText(SESSION_RECORDING_TITLE); assert.dom(`[href="${urls.sessionRecordings}"]`).doesNotExist(); }); - - // TODO: When we add abilities to session-recordings this test will be refactor to account for it. - test('user can navigate to a session recording', async function (assert) { - assert.expect(2); - // Visit session recordings - await visit(urls.sessionRecordings); - assert.dom('table').hasClass('hds-table'); - // Click a session recording and check it navigates properly - await click(LIST_SESSION_RECORDING_BUTTON); - assert.strictEqual(currentURL(), urls.sessionRecording); - }); }); diff --git a/ui/admin/tests/acceptance/session-recordings/session-recording/session-recording-test.js b/ui/admin/tests/acceptance/session-recordings/read-test.js similarity index 60% rename from ui/admin/tests/acceptance/session-recordings/session-recording/session-recording-test.js rename to ui/admin/tests/acceptance/session-recordings/read-test.js index 0a91ad99d..8d5c60a9e 100644 --- a/ui/admin/tests/acceptance/session-recordings/session-recording/session-recording-test.js +++ b/ui/admin/tests/acceptance/session-recordings/read-test.js @@ -2,13 +2,16 @@ import { module, test } from 'qunit'; import { visit, currentURL, click } from '@ember/test-helpers'; import { setupApplicationTest } from 'admin/tests/helpers'; import setupMirage from 'ember-cli-mirage/test-support/setup-mirage'; +import a11yAudit from 'ember-a11y-testing/test-support/audit'; import { authenticateSession } from 'ember-simple-auth/test-support'; -module('Acceptance | session recordings | session recording', function (hooks) { +module('Acceptance | session recordings | read', function (hooks) { setupApplicationTest(hooks); setupMirage(hooks); // Selectors + const LIST_SESSION_RECORDING_BUTTON = + 'table > tbody > tr > td:last-child > a'; const LIST_CHANNEL_RECORDING_BUTTON = 'table > tbody > tr > td:last-child > a'; @@ -50,14 +53,43 @@ module('Acceptance | session recordings | session recording', function (hooks) { authenticateSession({}); }); - test('user can navigate to a session recording', async function (assert) { + test('visiting a session recording', async function (assert) { assert.expect(1); + // Visit session recordings + await visit(urls.sessionRecordings); + await a11yAudit(); + + // Click a session recording and check it navigates properly + await click(LIST_SESSION_RECORDING_BUTTON); + await a11yAudit(); - // Visit session recording - await visit(urls.sessionRecording); assert.strictEqual(currentURL(), urls.sessionRecording); }); + test('user can navigate to a session recording with proper authorization', async function (assert) { + assert.expect(3); + // Visit session recordings + await visit(urls.sessionRecordings); + + assert.true(instances.sessionRecording.authorized_actions.includes('read')); + assert.dom(`[href="${urls.sessionRecording}"]`).exists(); + // Click a session recording and check it navigates properly + await click(LIST_SESSION_RECORDING_BUTTON); + assert.strictEqual(currentURL(), urls.sessionRecording); + }); + + test('user cannot navigate to a session recording without the read action', async function (assert) { + assert.expect(1); + instances.sessionRecording.authorized_actions = + instances.sessionRecording.authorized_actions.filter( + (item) => item !== 'read' + ); + + // Visit session recordings + await visit(urls.sessionRecordings); + assert.dom(LIST_SESSION_RECORDING_BUTTON).doesNotExist(); + }); + test('user can navigate to a channel recording', async function (assert) { assert.expect(2); From 0349b4c8049d700e40bbdbeec34f2e788221590c Mon Sep 17 00:00:00 2001 From: Cameron Perera Date: Thu, 30 Mar 2023 15:02:00 -0500 Subject: [PATCH 101/193] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20add=20View=20tex?= =?UTF-8?q?t=20to=20session=20recording=20list=20item=20button=20(#171)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- addons/core/translations/actions/en-us.yaml | 1 + addons/core/translations/resources/en-us.yaml | 1 - .../templates/scopes/scope/session-recordings/index.hbs | 7 ++----- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/addons/core/translations/actions/en-us.yaml b/addons/core/translations/actions/en-us.yaml index 07e09b542..adf25337e 100644 --- a/addons/core/translations/actions/en-us.yaml +++ b/addons/core/translations/actions/en-us.yaml @@ -19,6 +19,7 @@ deny: Deny help: Need help? next: Next back: Back +view: View retry: Retry get-topic-help: Get help for this topic copy-to-clipboard: Copy to Clipboard diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml index 010d964b8..680e5c0fa 100644 --- a/addons/core/translations/resources/en-us.yaml +++ b/addons/core/translations/resources/en-us.yaml @@ -216,7 +216,6 @@ session-recording: title_plural: Session Recordings details: Session details related: Related - button-aria-label: Go to session recording {id} connection: title: Connection title_plural: Connections diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs index 95333b716..3e181c407 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs @@ -64,12 +64,9 @@ {{#if (can 'read session-recording' B.data)}} From b9fea822d0dd575acdb3fdc4a768b08984f248d7 Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Corvo Date: Thu, 30 Mar 2023 17:00:02 -0700 Subject: [PATCH 102/193] Feat - ICU 8234 helper format-bytes-size (#170) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 🎸 Add format-bytes-size helper --- .../core/addon/helpers/format-bytes-size.js | 12 + addons/core/app/helpers/format-bytes-size.js | 1 + addons/core/package.json | 1 + .../helpers/format-bytes-size-test.js | 92 + .../channels-by-connection/channel.hbs | 4 +- .../session-recording/index.hbs | 8 +- yarn.lock | 2215 ++++++----------- 7 files changed, 851 insertions(+), 1482 deletions(-) create mode 100644 addons/core/addon/helpers/format-bytes-size.js create mode 100644 addons/core/app/helpers/format-bytes-size.js create mode 100644 addons/core/tests/integration/helpers/format-bytes-size-test.js diff --git a/addons/core/addon/helpers/format-bytes-size.js b/addons/core/addon/helpers/format-bytes-size.js new file mode 100644 index 000000000..339b62e51 --- /dev/null +++ b/addons/core/addon/helpers/format-bytes-size.js @@ -0,0 +1,12 @@ +import { helper } from '@ember/component/helper'; +import filesize from 'file-size'; + +/** + * Takes a int expressing file size in bytes and returns a conversion + * into a human-readable string. + * "e.g. {{format-bytes-size 164730000}} // 164,73 MB" + */ +export default helper(function formatBytesSize([sizeInBytes]) { + const numberOfBytes = Number(sizeInBytes); + return filesize(numberOfBytes).human('si'); +}); diff --git a/addons/core/app/helpers/format-bytes-size.js b/addons/core/app/helpers/format-bytes-size.js new file mode 100644 index 000000000..3409ec92e --- /dev/null +++ b/addons/core/app/helpers/format-bytes-size.js @@ -0,0 +1 @@ +export { default } from 'core/helpers/format-bytes-size'; diff --git a/addons/core/package.json b/addons/core/package.json index c3af48918..0d1ee1cf4 100644 --- a/addons/core/package.json +++ b/addons/core/package.json @@ -41,6 +41,7 @@ "ember-intl": "^6.0.0-beta.4", "ember-loading": "^2.0.0", "ember-truth-helpers": "^3.0.0", + "file-size": "^1.0.0", "intl-unofficial-duration-unit-format": "^3.1.0" }, "devDependencies": { diff --git a/addons/core/tests/integration/helpers/format-bytes-size-test.js b/addons/core/tests/integration/helpers/format-bytes-size-test.js new file mode 100644 index 000000000..3f0becb59 --- /dev/null +++ b/addons/core/tests/integration/helpers/format-bytes-size-test.js @@ -0,0 +1,92 @@ +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'dummy/tests/helpers'; +import { render } from '@ember/test-helpers'; +import { hbs } from 'ember-cli-htmlbars'; + +module('Integration | Helper | format-bytes-size', function (hooks) { + setupRenderingTest(hooks); + + test('it renders file size in human-readable string', async function (assert) { + assert.expect(16); + // Size to kB + const expectedSizeKb = '108.93 kB'; + this.set('inputNumberSizeKb', 108930); + this.set('inputStringSizeKb', '108930'); + + await render(hbs`{{format-bytes-size this.inputNumberSizeKb}}`); + assert.dom(this.element).hasText(expectedSizeKb); + await render(hbs`{{format-bytes-size this.inputStringSizeKb}}`); + assert.dom(this.element).hasText(expectedSizeKb); + + // Size to MB + const expectedSizeMb = '164.73 MB'; + this.set('inputNumberSizeMb', 164730000); + this.set('inputStringSizeMb', '164730000'); + + await render(hbs`{{format-bytes-size this.inputNumberSizeMb}}`); + assert.dom(this.element).hasText(expectedSizeMb); + await render(hbs`{{format-bytes-size this.inputStringSizeMb}}`); + assert.dom(this.element).hasText(expectedSizeMb); + + // Size to GB + const expectedSizeGb = '2.15 GB'; + this.set('inputNumberSizeGb', 2147483647); + this.set('inputStringSizeGb', '2147483647'); + + await render(hbs`{{format-bytes-size this.inputNumberSizeGb}}`); + assert.dom(this.element).hasText(expectedSizeGb); + await render(hbs`{{format-bytes-size this.inputStringSizeGb}}`); + assert.dom(this.element).hasText(expectedSizeGb); + + // Size to TB + const expectedSizeTb = '12.37 TB'; + this.set('inputNumberSizeTb', 12370000000000); + this.set('inputStringSizeTb', '12370000000000'); + + await render(hbs`{{format-bytes-size this.inputNumberSizeTb}}`); + assert.dom(this.element).hasText(expectedSizeTb); + await render(hbs`{{format-bytes-size this.inputStringSizeTb}}`); + assert.dom(this.element).hasText(expectedSizeTb); + + // Size to PB + const expectedSizePb = '9.01 PB'; + this.set('inputNumberSizePb', 9007199254740991); + this.set('inputStringSizePb', '9007199254740991'); + + await render(hbs`{{format-bytes-size this.inputNumberSizePb}}`); + assert.dom(this.element).hasText(expectedSizePb); + await render(hbs`{{format-bytes-size this.inputStringSizePb}}`); + assert.dom(this.element).hasText(expectedSizePb); + + /* eslint-disable no-loss-of-precision */ + // Size to EB + const expectedSizeEb = '1.24 EB'; + this.set('inputNumberSizeEb', 1237000000000000000); + this.set('inputStringSizeEb', '1237000000000000000'); + + await render(hbs`{{format-bytes-size this.inputNumberSizeEb}}`); + assert.dom(this.element).hasText(expectedSizeEb); + await render(hbs`{{format-bytes-size this.inputStringSizeEb}}`); + assert.dom(this.element).hasText(expectedSizeEb); + + // Size to ZB + const expectedSizeZb = '900.72 ZB'; + this.set('inputNumberSizeZb', 900719985474899195498367); + this.set('inputStringSizeZb', '900719985474899195498367'); + + await render(hbs`{{format-bytes-size this.inputNumberSizeZb}}`); + assert.dom(this.element).hasText(expectedSizeZb); + await render(hbs`{{format-bytes-size this.inputStringSizeZb}}`); + assert.dom(this.element).hasText(expectedSizeZb); + + // Size to YB + const expectedSizeYb = '90.07 YB'; + this.set('inputNumberSizeYb', 90071992547409919549836723); + this.set('inputStringSizeYb', '90071992547409919549836723'); + + await render(hbs`{{format-bytes-size this.inputNumberSizeYb}}`); + assert.dom(this.element).hasText(expectedSizeYb); + await render(hbs`{{format-bytes-size this.inputStringSizeYb}}`); + assert.dom(this.element).hasText(expectedSizeYb); + }); +}); diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs index 14e5eb47a..e9e9ce63d 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs @@ -46,13 +46,13 @@ {{! Bytes up }}

- {{@model.channelRecording.bytes_up}} + {{format-bytes-size @model.channelRecording.bytes_up}}

{{! Bytes down }}

- {{@model.channelRecording.bytes_down}} + {{format-bytes-size @model.channelRecording.bytes_down}}

{{! Errors }} diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs index 2731de566..6eaebe465 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs @@ -53,9 +53,9 @@ - {{B.data.bytes_up}} + {{format-bytes-size B.data.bytes_up}} - {{B.data.bytes_down}} + {{format-bytes-size B.data.bytes_down}} @@ -96,13 +96,13 @@ {{! Bytes up }}

- {{@model.sessionRecording.bytes_up}} + {{format-bytes-size @model.sessionRecording.bytes_up}}

{{! Bytes down }}

- {{@model.sessionRecording.bytes_down}} + {{format-bytes-size @model.sessionRecording.bytes_down}}

{{! Related }} diff --git a/yarn.lock b/yarn.lock index ca9146b67..07b43c7a1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4659,32 +4659,6 @@ resolved "https://registry.yarnpkg.com/@handlebars/parser/-/parser-2.0.0.tgz#5e8b7298f31ff8f7b260e6b7363c7e9ceed7d9c5" integrity sha512-EP9uEDZv/L5Qh9IWuMUGJRfwhXJ4h1dqKTT4/3+tY0eu7sPis7xh23j61SYUnNF4vqCQvvUXpDo9Bh/+q1zASA== -"@hapi/b64@5.x.x": - version "5.0.0" - resolved "https://registry.yarnpkg.com/@hapi/b64/-/b64-5.0.0.tgz#b8210cbd72f4774985e78569b77e97498d24277d" - integrity sha512-ngu0tSEmrezoiIaNGG6rRvKOUkUuDdf4XTPnONHGYfSGRmDqPZX5oJL6HAdKTo1UQHECbdB4OzhWrfgVppjHUw== - dependencies: - "@hapi/hoek" "9.x.x" - -"@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/cryptiles@5.x.x": - version "5.1.0" - resolved "https://registry.yarnpkg.com/@hapi/cryptiles/-/cryptiles-5.1.0.tgz#655de4cbbc052c947f696148c83b187fc2be8f43" - integrity sha512-fo9+d1Ba5/FIoMySfMqPBR/7Pa29J2RsiPrl7bkwo5W5o+AN1dAYQRi4SPrPwwVxVGKjgLOEWrsvt1BonJSfLA== - 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== - "@hashicorp/design-system-components@^1.5.1": version "1.5.1" resolved "https://registry.yarnpkg.com/@hashicorp/design-system-components/-/design-system-components-1.5.1.tgz#ed02dd834db2d254f2dc6c108f3520ddf3268de3" @@ -4763,14 +4737,6 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== -"@iarna/cli@^2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@iarna/cli/-/cli-2.1.0.tgz#f830356d54c72c804bd7afc43999de31e40fc3d6" - integrity sha512-rvVVqDa2g860niRbqs3D5RhL4la3dc1vwk+NlpKPZxKaMSHtE2se6C2x8NeveN+rcjp3/686X+u+09CZ+7lmAQ== - dependencies: - glob "^7.1.2" - signal-exit "^3.0.2" - "@istanbuljs/load-nyc-config@^1.0.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" @@ -5197,11 +5163,6 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@npmcli/ci-detect@^1.0.0": - version "1.4.0" - resolved "https://registry.yarnpkg.com/@npmcli/ci-detect/-/ci-detect-1.4.0.tgz#18478bbaa900c37bfbd8a2006a6262c62e8b0fe1" - integrity sha512-3BGrt6FLjqM6br5AhWRKTr3u5GIVkjRYeAFrMp3HjnfICrg4xOrVRwFavKT6tsp++bq5dluL5t8ME/Nha/6c1Q== - "@npmcli/fs@^1.0.0": version "1.1.1" resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-1.1.1.tgz#72f719fe935e687c56a4faecf3c03d06ba593257" @@ -5256,6 +5217,11 @@ resolved "https://registry.yarnpkg.com/@simple-dom/interface/-/interface-1.4.0.tgz#e8feea579232017f89b0138e2726facda6fbb71f" integrity sha512-l5qumKFWU0S+4ZzMaLXFU8tQZsicHEMEyAxI5kDFGhJsRqDwe0a7/iPA/GdxlGyDKseQQAgIz5kzU7eXTrlSpA== +"@sindresorhus/is@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" + integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== + "@sindresorhus/is@^4.0.0": version "4.0.1" resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.0.1.tgz#d26729db850fa327b7cacc5522252194404226f5" @@ -7172,6 +7138,13 @@ resolve-from "^5.0.0" store2 "^2.12.0" +"@szmarczak/http-timer@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" + integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA== + dependencies: + defer-to-connect "^1.0.1" + "@szmarczak/http-timer@^4.0.5": version "4.0.6" resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.6.tgz#b4a914bb62e7c272d4e5989fe4440f812ab1d807" @@ -8052,14 +8025,6 @@ resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31" integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ== -JSONStream@^1.3.5: - version "1.3.5" - resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" - integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ== - dependencies: - jsonparse "^1.2.0" - through ">=2.2.7 <3" - JSV@^4.0.x: version "4.0.2" resolved "https://registry.yarnpkg.com/JSV/-/JSV-4.0.2.tgz#d077f6825571f82132f9dffaed587b4029feff57" @@ -8070,7 +8035,7 @@ abab@^2.0.3, abab@^2.0.5: resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== -abbrev@1, abbrev@~1.1.1: +abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== @@ -8158,13 +8123,6 @@ address@1.1.2, address@^1.0.1: resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6" integrity sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA== -agent-base@4, agent-base@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee" - integrity sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg== - dependencies: - es6-promisify "^5.0.0" - agent-base@5: version "5.1.1" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-5.1.1.tgz#e8fb3f242959db44d63be665db7a8e739537a32c" @@ -8177,20 +8135,6 @@ agent-base@6, agent-base@^6.0.2: dependencies: debug "4" -agent-base@~4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9" - integrity sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg== - dependencies: - es6-promisify "^5.0.0" - -agentkeepalive@^3.4.1: - version "3.5.2" - resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-3.5.2.tgz#a113924dd3fa24a0bc3b78108c450c2abee00f67" - integrity sha512-e0L/HNe6qkQ7H19kTlRRqUibEAwDK5AFk6y3PtMsuut2VAH6+Q4xZml1tNDJD7kSAyqmbG/K08K5WEJYtUrSlQ== - dependencies: - humanize-ms "^1.2.1" - agentkeepalive@^4.1.3: version "4.2.1" resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.2.1.tgz#a7975cbb9f83b367f06c90cc51ff28fe7d499717" @@ -8305,13 +8249,6 @@ anchor-markdown-header@^0.5.7: dependencies: emoji-regex "~6.1.0" -ansi-align@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-2.0.0.tgz#c36aeccba563b89ceb556f3690f0b1d9e3547f7f" - integrity sha512-TdlOggdA/zURfMYa7ABC66j+oqfMew58KpJMbUlH3bcZP1b+cBHIHDDn5uH9INsxrHBPjsqM0tDB4jPTF/vgJA== - dependencies: - string-width "^2.0.0" - ansi-align@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.0.tgz#b536b371cf687caaef236c18d3e21fe3797467cb" @@ -8341,22 +8278,42 @@ ansi-escapes@^4.2.1, ansi-escapes@^4.3.0: dependencies: type-fest "^0.21.3" -ansi-html@0.0.7, ansi-html@^0.0.7, ansi-html@^0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.8.tgz#e969db193b12bcdfa6727b29ffd8882dc13cc501" - integrity sha512-QROYz1I1Kj+8bTYgx0IlMBpRSCIU+7GjbE0oH+KF7QKc+qSF8YAlIutN59Db17tXN70Ono9upT9Ht0iG93W7ug== +ansi-html@0.0.7, ansi-html@^0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.7.tgz#813584021962a9e9e6fd039f940d12f56ca7859e" + integrity sha512-JoAxEa1DfP9m2xfB/y2r/aKcwXNlltr4+0QSBC4TrLfcxyvepX2Pv0t/xpgGV5bGsDzCYV8SzjWgyCW0T9yYbA== -ansi-regex@^2.0.0, ansi-regex@^3.0.0, ansi-regex@^4.1.0, ansi-regex@^5.0.0, ansi-regex@^5.0.1, ansi-regex@^6.0.1: +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA== + +ansi-regex@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.1.tgz#123d6479e92ad45ad897d4054e3c7ca7db4944e1" + integrity sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw== + +ansi-regex@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.1.tgz#164daac87ab2d6f6db3a29875e2d1766582dabed" + integrity sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g== + +ansi-regex@^5.0.0, 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-regex@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" + integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== + ansi-styles@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= -ansi-styles@^3.0.0, ansi-styles@^3.2.0, ansi-styles@^3.2.1: +ansi-styles@^3.0.0, ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== @@ -8397,16 +8354,6 @@ ansicolors@~0.2.1: resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.2.1.tgz#be089599097b74a5c9c4a84a0cdbcdb62bd87aef" integrity sha1-vgiVmQl7dKXJxKhKDNvNtivYeu8= -ansicolors@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.3.2.tgz#665597de86a9ffe3aa9bfbe6cae5c6ea426b4979" - integrity sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg== - -ansistyles@~0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/ansistyles/-/ansistyles-0.1.3.tgz#5de60415bda071bb37127854c864f41b23254539" - integrity sha512-6QWEyvMgIXX0eO972y7YPBLSBsq7UWKFAoNNTLGaOJ9bstcEL9sCbcjf96dVfNDdUsRoGOK82vWFJlKApXds7g== - anymatch@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" @@ -8428,21 +8375,16 @@ app-root-dir@^1.0.2: resolved "https://registry.yarnpkg.com/app-root-dir/-/app-root-dir-1.0.2.tgz#38187ec2dea7577fff033ffcb12172692ff6e118" integrity sha1-OBh+wt6nV3//Az/8sSFyaS/24Rg= -aproba@^1.0.3, aproba@^1.1.1, aproba@^1.1.2: +aproba@^1.0.3, aproba@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== -"aproba@^1.0.3 || ^2.0.0", "aproba@^1.1.2 || 2", aproba@^2.0.0: +"aproba@^1.0.3 || ^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== -archy@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" - integrity sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw== - are-we-there-yet@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz#372e0e7bd279d8e94c653aaa1f67200884bf3e1c" @@ -8467,7 +8409,7 @@ are-we-there-yet@~1.1.2: delegates "^1.0.0" readable-stream "^2.0.6" -argparse@^1.0.7: +argparse@^1.0.7, argparse@~1.0.2: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== @@ -8634,6 +8576,11 @@ asn1.js@^5.2.0: minimalistic-assert "^1.0.0" safer-buffer "^2.1.0" +asn1@0.1.11: + version "0.1.11" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.1.11.tgz#559be18376d08a4ec4dbe80877d27818639b2df7" + integrity sha512-Fh9zh3G2mZ8qM/kwsiKwL2U2FmXxVsboP4x1mXjnhKHv3SmzaBZoYvxEQJz/YS2gnCgd8xlAVWcZnQyC9qZBsA== + asn1@~0.2.3: version "0.2.4" resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" @@ -8651,6 +8598,11 @@ assert-plus@1.0.0, assert-plus@^1.0.0: resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= +assert-plus@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.1.5.tgz#ee74009413002d84cec7219c6ac811812e723160" + integrity sha512-brU24g7ryhRwGCI2y+1dGQmQXiZF7TtIj583S96y0jjdajIe6wn8BuXyELYhvD22dtIxDQVFk04YTJwwdwOYJw== + assert@^1.1.1: version "1.5.0" resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb" @@ -8712,6 +8664,11 @@ async-each@^1.0.1: resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== +async-limiter@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" + integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== + async-promise-queue@^1.0.3, async-promise-queue@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/async-promise-queue/-/async-promise-queue-1.0.5.tgz#cb23bce9fce903a133946a700cc85f27f09ea49d" @@ -8720,13 +8677,28 @@ async-promise-queue@^1.0.3, async-promise-queue@^1.0.5: async "^2.4.1" debug "^2.6.8" -async@^2.4.1, async@^2.6.2, async@^2.6.4, async@~0.2.9, async@~1.0.0: +async@^2.4.1, async@^2.6.2, async@^2.6.4: version "2.6.4" resolved "https://registry.yarnpkg.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221" integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA== dependencies: lodash "^4.17.14" +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== + +async@~0.9.0: + version "0.9.2" + resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d" + integrity sha512-l6ToIJIotphWahxxHyzK9bnLR6kM4jJIIgLShZeqLY7iboHoGkdgFl7W2/Ivi4SkMJYGKqW8vSuk0uKUj6qsSw== + +async@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/async/-/async-1.0.0.tgz#f8fc04ca3a13784ade9e1641af98578cfbd647a9" + integrity sha512-5mO7DX4CbJzp9zjaFXusQQ4tzKJARjNB1Ih1pVBi8wkbmXy/xzIDgEMXxWePLzt2OdFwaxfneIlT1nCiXubrPQ== + asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" @@ -8760,6 +8732,11 @@ autoprefixer@^9.8.6: postcss "^7.0.32" postcss-value-parser "^4.1.0" +aws-sign2@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.5.0.tgz#c57103f7a17fc037f02d7c2e64b602ea223f7d63" + integrity sha512-oqUX0DM5j7aPWPCnpWebiyNIj2wiNI87ZxnOMoGv0aE4TGlBy2N+5iWc6dQ/NOKZaBD2W6PVz8jtOGkWzSC5EA== + aws-sign2@~0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" @@ -9312,7 +9289,7 @@ base-64@^0.1.0: resolved "https://registry.yarnpkg.com/base-64/-/base-64-0.1.0.tgz#780a99c84e7d600260361511c4877613bf24f6bb" integrity sha1-eAqZyE59YAJgNhURxId2E78k9rs= -base64-js@^1.0.2, base64-js@^1.5.1: +base64-js@^1.0.2, base64-js@^1.3.1, base64-js@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== @@ -9366,18 +9343,6 @@ big.js@^5.2.2: resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== -bin-links@^1.1.2, bin-links@^1.1.8: - version "1.1.8" - resolved "https://registry.yarnpkg.com/bin-links/-/bin-links-1.1.8.tgz#bd39aadab5dc4bdac222a07df5baf1af745b2228" - integrity sha512-KgmVfx+QqggqP9dA3iIc5pA4T1qEEEL+hOhOhNPaUm77OTrJoOXE/C05SJLNJe6m/2wUK7F1tDSou7n5TfCDzQ== - dependencies: - bluebird "^3.5.3" - cmd-shim "^3.0.0" - gentle-fs "^2.3.0" - graceful-fs "^4.1.15" - npm-normalize-package-bin "^1.0.0" - write-file-atomic "^2.3.0" - binary-extensions@^1.0.0: version "1.13.1" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" @@ -9400,20 +9365,21 @@ bindings@^1.5.0: dependencies: file-uri-to-path "1.0.0" -bl@^4.1.0, bl@~1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.3.tgz#1e8dd80142eac80d7158c9dccc047fb620e035e7" - integrity sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww== +bl@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" + integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== dependencies: - readable-stream "^2.3.5" - safe-buffer "^5.1.1" + buffer "^5.5.0" + inherits "^2.0.4" + readable-stream "^3.4.0" blank-object@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/blank-object/-/blank-object-1.0.2.tgz#f990793fbe9a8c8dd013fb3219420bec81d5f4b9" integrity sha1-+ZB5P76ajI3QE/syGUIL7IHV9Lk= -bluebird@^3.1.1, bluebird@^3.3.5, bluebird@^3.4.6, bluebird@^3.5.0, bluebird@^3.5.1, bluebird@^3.5.3, bluebird@^3.5.5, bluebird@^3.7.2: +bluebird@^3.1.1, bluebird@^3.3.5, bluebird@^3.4.6, bluebird@^3.5.0, 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== @@ -9456,7 +9422,7 @@ body@^5.1.0: raw-body "~1.1.0" safe-json-parse "~1.0.1" -boolbase@^1.0.0: +boolbase@^1.0.0, boolbase@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= @@ -9471,12 +9437,12 @@ boolean@^3.1.4: resolved "https://registry.yarnpkg.com/boolean/-/boolean-3.2.0.tgz#9e5294af4e98314494cbb17979fa54ca159f116b" integrity sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw== -boom@7.x.x: - version "7.3.0" - resolved "https://registry.yarnpkg.com/boom/-/boom-7.3.0.tgz#733a6d956d33b0b1999da3fe6c12996950d017b9" - integrity sha512-Swpoyi2t5+GhOEGw8rEsKvTxFLIDiiKoUc2gsoV6Lyr43LHBIzch3k2MvYUs8RTROrIkVJ3Al0TkaOGjnb+B6A== +boom@0.4.x: + version "0.4.2" + resolved "https://registry.yarnpkg.com/boom/-/boom-0.4.2.tgz#7a636e9ded4efcefb19cef4947a3c67dfaee911b" + integrity sha512-OvfN8y1oAxxphzkl2SnCS+ztV/uVKTATtgLjWYg/7KwcNyf3rzpHxNQJZCKtsZd4+MteKczhWbSjtEX4bGgU9g== dependencies: - hoek "6.x.x" + hoek "0.9.x" bower-config@^1.4.3: version "1.4.3" @@ -9495,19 +9461,6 @@ bower-endpoint-parser@0.2.2: resolved "https://registry.yarnpkg.com/bower-endpoint-parser/-/bower-endpoint-parser-0.2.2.tgz#00b565adbfab6f2d35addde977e97962acbcb3f6" integrity sha1-ALVlrb+rby01rd3pd+l5Yqy8s/Y= -boxen@^1.2.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b" - integrity sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw== - dependencies: - ansi-align "^2.0.0" - camelcase "^4.0.0" - chalk "^2.0.1" - cli-boxes "^1.0.0" - string-width "^2.0.0" - term-size "^1.2.0" - widest-line "^2.0.0" - boxen@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/boxen/-/boxen-4.2.0.tgz#e411b62357d6d6d36587c8ac3d5d974daa070e64" @@ -10241,7 +10194,17 @@ browserify-zlib@^0.2.0: dependencies: pako "~1.0.5" -browserslist@4.14.2, browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.16.5, browserslist@^4.16.6, browserslist@^4.16.7, browserslist@^4.17.3, browserslist@^4.17.5, browserslist@^4.19.1, browserslist@^4.20.2, browserslist@^4.21.0, browserslist@^4.21.3: +browserslist@4.14.2: + version "4.14.2" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.14.2.tgz#1b3cec458a1ba87588cc5e9be62f19b6d48813ce" + integrity sha512-HI4lPveGKUR0x2StIz+2FXfDk9SfVMrxn6PLh1JeGUwcuoDkdKZebWiyLRJ68iIPDpMI4JLVDf7S7XzslgWOhw== + dependencies: + caniuse-lite "^1.0.30001125" + electron-to-chromium "^1.3.564" + escalade "^3.0.2" + node-releases "^1.1.61" + +browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.16.6, browserslist@^4.16.7, browserslist@^4.17.3, browserslist@^4.17.5, browserslist@^4.19.1, browserslist@^4.20.2, browserslist@^4.21.0, browserslist@^4.21.3: version "4.21.5" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.5.tgz#75c5dae60063ee641f977e00edd3cfb2fb7af6a7" integrity sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w== @@ -10305,6 +10268,14 @@ buffer@^4.3.0: ieee754 "^1.1.4" isarray "^1.0.0" +buffer@^5.5.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" @@ -10322,16 +10293,6 @@ builtins@^5.0.0: dependencies: semver "^7.0.0" -byline@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/byline/-/byline-5.0.0.tgz#741c5216468eadc457b03410118ad77de8c1ddb1" - integrity sha512-s6webAy+R4SR8XVuJWt2V2rGvhnrhxN+9S15GNuTK3wKPOXFF6RNc+8ug2XhH+2s4f+uudG4kUVYmYOQWL2g0Q== - -byte-size@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/byte-size/-/byte-size-5.0.1.tgz#4b651039a5ecd96767e71a3d7ed380e48bed4191" - integrity sha512-/XuKeqWocKsYa/cBY1YbSJSWWqTi4cFgr9S6OyM7PBaPbr9zvNGwWP33vt0uqGhwDdN+y3yhbXVILEUpnwEWGw== - bytes@1: version "1.0.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-1.0.0.tgz#3569ede8ba34315fab99c3e92cb04c7220de1fa8" @@ -10347,7 +10308,7 @@ bytes@3.1.2: resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== -cacache@^12.0.0, cacache@^12.0.2, cacache@^12.0.4: +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== @@ -10435,6 +10396,19 @@ cacheable-lookup@^5.0.3: resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz#5a6b865b2c44357be3d5ebc2a467b032719a7005" integrity sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA== +cacheable-request@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912" + integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg== + dependencies: + clone-response "^1.0.2" + get-stream "^5.1.0" + http-cache-semantics "^4.0.0" + keyv "^3.0.0" + lowercase-keys "^2.0.0" + normalize-url "^4.1.0" + responselike "^1.0.2" + cacheable-request@^7.0.2: version "7.0.2" resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.2.tgz#ea0d0b889364a25854757301ca12b2da77f91d27" @@ -10468,11 +10442,6 @@ call-bind@^1.0.0, call-bind@^1.0.2: function-bind "^1.1.1" get-intrinsic "^1.0.2" -call-limit@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/call-limit/-/call-limit-1.1.1.tgz#ef15f2670db3f1992557e2d965abc459e6e358d4" - integrity sha512-5twvci5b9eRBw2wCfPtN0GmlR2/gadZqyFpPhOK6CvMFoFgA+USnZ6Jpu1lhG9h85pQ3Ouil3PfXWRD4EUaRiQ== - call-me-maybe@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" @@ -10518,11 +10487,6 @@ camelcase@^2.0.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8= -camelcase@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" - integrity sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw== - camelcase@^5.3.1: version "5.3.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" @@ -10550,11 +10514,16 @@ caniuse-api@^3.0.0: lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001157, caniuse-lite@^1.0.30001449: +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001449: version "1.0.30001466" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001466.tgz#c1e6197c540392e09709ecaa9e3e403428c53375" integrity sha512-ewtFBSfWjEmxUgNBSZItFSmVtvk9zkwkl1OfRZlKA8slltRN+/C/tuGVrF9styXkN36Yu3+SeJ1qkXxDEyNZ5w== +caniuse-lite@^1.0.30001125: + version "1.0.30001472" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001472.tgz#3f484885f2a2986c019dc416e65d9d62798cdd64" + integrity sha512-xWC/0+hHHQgj3/vrKYY0AAzeIUgr7L9wlELIcAvZdDUHlhL/kNxMdnQLOSOQfP8R51ZzPhmHdyMkI0MMpmxCfg== + capture-exit@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4" @@ -10720,7 +10689,7 @@ chokidar@^2.1.8: optionalDependencies: fsevents "^1.2.7" -chownr@^1.1.1, chownr@^1.1.2, chownr@^1.1.4: +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== @@ -10740,11 +10709,6 @@ chromium-pickle-js@^0.2.0: resolved "https://registry.yarnpkg.com/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz#04a106672c18b085ab774d983dfa3ea138f22205" integrity sha1-BKEGZywYsIWrd02YPfo+oTjyIgU= -ci-info@^1.5.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" - integrity sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A== - ci-info@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" @@ -10760,13 +10724,6 @@ ci-info@^3.3.2: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.3.2.tgz#6d2967ffa407466481c6c90b6e16b3098f080128" integrity sha512-xmDt/QIAdeZ9+nfdPsaBCpMvHNLFiLdjj59qjqn+6iPe6YmHGQ35sBnQ8uslRBXFmXkiZQOJRjvQeoGppoTjjg== -cidr-regex@^2.0.10: - version "2.0.10" - resolved "https://registry.yarnpkg.com/cidr-regex/-/cidr-regex-2.0.10.tgz#af13878bd4ad704de77d6dc800799358b3afa70d" - integrity sha512-sB3ogMQXWvreNPbJUZMRApxuRYd+KoIo4RGQ81VatjmMW6WJPo+IJZ2846FGItr9VzKo5w7DXzijPLGtSd0N3Q== - dependencies: - ip-regex "^2.1.0" - 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" @@ -10814,7 +10771,15 @@ clean-css-promise@^0.1.0: clean-css "^3.4.5" pinkie-promise "^2.0.0" -clean-css@^3.4.5, clean-css@^4.1.11, clean-css@^4.2.3: +clean-css@^3.4.5: + version "3.4.28" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-3.4.28.tgz#bf1945e82fc808f55695e6ddeaec01400efd03ff" + integrity sha512-aTWyttSdI2mYi07kWqHi24NUU9YlELFKGOAgFzZjDN1064DMAOy2FBuoyGmkKRlXkbpXd0EVHmiVkbKhKoirTw== + dependencies: + commander "2.8.x" + source-map "0.4.x" + +clean-css@^4.2.3: version "4.2.4" resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.4.tgz#733bf46eba4e607c6891ea57c24a989356831178" integrity sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A== @@ -10831,24 +10796,11 @@ clean-up-path@^1.0.0: resolved "https://registry.yarnpkg.com/clean-up-path/-/clean-up-path-1.0.0.tgz#de9e8196519912e749c9eaf67c13d64fac72a3e5" integrity sha512-PHGlEF0Z6976qQyN6gM7kKH6EH0RdfZcc8V+QhFe36eRxV0SMH5OUBZG7Bxa9YcreNzyNbK63cGiZxdSZgosRw== -cli-boxes@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" - integrity sha512-3Fo5wu8Ytle8q9iCzS4D2MWVL2X7JVWRiS1BnXbTFDhS9c/REkM9vd1AmabsoZoY5/dGi5TT9iKL8Kb6DeBRQg== - cli-boxes@^2.2.0, cli-boxes@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== -cli-columns@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/cli-columns/-/cli-columns-3.1.2.tgz#6732d972979efc2ae444a1f08e08fa139c96a18e" - integrity sha512-iQYpDgpPPmCjn534ikQOhi+ydP6uMar+DtJ6a0In4aGL/PKqWfao75s6eF81quQQaz7isGz+goNECLARRZswdg== - dependencies: - string-width "^2.0.0" - strip-ansi "^3.0.1" - cli-cursor@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" @@ -10886,16 +10838,6 @@ cli-table3@0.6.0, cli-table3@^0.6.0: optionalDependencies: colors "^1.1.2" -cli-table3@^0.5.0, cli-table3@^0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.5.1.tgz#0252372d94dfc40dbd8df06005f48f31f656f202" - integrity sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw== - dependencies: - object-assign "^4.1.0" - string-width "^2.1.1" - optionalDependencies: - colors "^1.1.2" - cli-table3@^0.6.1: version "0.6.3" resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.3.tgz#61ab765aac156b52f222954ffc607a6f01dbeeb2" @@ -10956,15 +10898,6 @@ clipboard@^2.0.8: select "^1.1.2" tiny-emitter "^2.0.0" -cliui@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" - integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== - dependencies: - string-width "^3.1.0" - strip-ansi "^5.2.0" - wrap-ansi "^5.1.0" - cliui@^7.0.2: version "7.0.4" resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" @@ -11000,14 +10933,6 @@ clone@^2.1.2: resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18= -cmd-shim@^3.0.0, cmd-shim@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/cmd-shim/-/cmd-shim-3.0.3.tgz#2c35238d3df37d98ecdd7d5f6b8dc6b21cadc7cb" - integrity sha512-DtGg+0xiFhQIntSBRzL2fRQBnmtAVwXIDo4Qq46HPpObYquxMaZS4sb82U9nH91qJrlosC1wa9gwr0QyL/HypA== - dependencies: - graceful-fs "^4.1.2" - mkdirp "~0.5.0" - co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" @@ -11104,14 +11029,6 @@ colors@^1.1.2, colors@^1.4.0: resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== -columnify@~1.5.4: - version "1.5.4" - resolved "https://registry.yarnpkg.com/columnify/-/columnify-1.5.4.tgz#4737ddf1c7b69a8a7c340570782e947eec8e78bb" - integrity sha512-rFl+iXVT1nhLQPfGDw+3WcS8rmm7XsLKUmhsGE3ihzzpIikeGrTaZPIRKYWeLsLBypsHzjXIvYEltVUZS84XxQ== - dependencies: - strip-ansi "^3.0.0" - wcwidth "^1.0.0" - combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" @@ -11119,11 +11036,25 @@ combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" +combined-stream@~0.0.4: + version "0.0.7" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-0.0.7.tgz#0137e657baa5a7541c57ac37ac5fc07d73b4dc1f" + integrity sha512-qfexlmLp9MyrkajQVyjEDb0Vj+KhRgR/rxLiVhaihlT+ZkX0lReqtH6Ack40CvMDERR4b5eFp3CreskpBs1Pig== + dependencies: + delayed-stream "0.0.5" + comma-separated-tokens@^1.0.0: version "1.0.8" resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz#632b80b6117867a158f1080ad498b2fbe7e3f5ea" integrity sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw== +commander@2.8.x: + version "2.8.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.8.1.tgz#06be367febfda0c330aa1e2a072d3dc9762425d4" + integrity sha512-+pJLBFVk+9ZZdlAOB5WuIElVPPth47hILFkmGym57aq8kwxsowvByvB0DHs1vQAhyMZzdcpTtF0VDKGkSDR4ZQ== + dependencies: + graceful-readlink ">= 1.0.0" + commander@2.9.0: version "2.9.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" @@ -11246,7 +11177,7 @@ concat-stream@^1.5.0, concat-stream@^1.6.2: readable-stream "^2.2.2" typedarray "^0.0.6" -config-chain@^1.1.11, config-chain@^1.1.13: +config-chain@^1.1.11: version "1.1.13" resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.13.tgz#fad0795aa6a6cdaff9ed1b68e9dff94372c232f4" integrity sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ== @@ -11254,18 +11185,6 @@ config-chain@^1.1.11, config-chain@^1.1.13: ini "^1.3.4" proto-list "~1.2.1" -configstore@^3.0.0: - version "3.1.5" - resolved "https://registry.yarnpkg.com/configstore/-/configstore-3.1.5.tgz#e9af331fadc14dabd544d3e7e76dc446a09a530f" - integrity sha512-nlOhI4+fdzoK5xmJ+NY+1gZK56bwEaWZr8fYuXohZ9Vkc1o3a4T/R3M+yE/w7x/ZVJ1zF8c+oaOvF0dztdUgmA== - dependencies: - dot-prop "^4.2.1" - graceful-fs "^4.1.2" - make-dir "^1.0.0" - unique-string "^1.0.0" - write-file-atomic "^2.0.0" - xdg-basedir "^3.0.0" - configstore@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/configstore/-/configstore-5.0.1.tgz#d365021b5df4b98cdd187d6a3b0e3f6a7cc5ed96" @@ -11588,15 +11507,6 @@ cross-spawn@7.0.3, cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.2, c shebang-command "^2.0.0" which "^2.0.1" -cross-spawn@^5.0.1: - version "5.1.0" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" - integrity sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A== - dependencies: - lru-cache "^4.0.1" - shebang-command "^1.2.0" - which "^1.2.9" - cross-spawn@^6.0.0, cross-spawn@^6.0.5: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" @@ -11608,12 +11518,12 @@ cross-spawn@^6.0.0, cross-spawn@^6.0.5: shebang-command "^1.2.0" which "^1.2.9" -cryptiles@~4.1.2: - version "4.1.3" - resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-4.1.3.tgz#2461d3390ea0b82c643a6ba79f0ed491b0934c25" - integrity sha512-gT9nyTMSUC1JnziQpPbxKGBbUg8VL7Zn2NB4E1cJYvuXdElHrwxrV9bmltZGDzet45zSDGyYceueke1TjynGzw== +cryptiles@0.2.x: + version "0.2.2" + resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-0.2.2.tgz#ed91ff1f17ad13d3748288594f8a48a0d26f325c" + integrity sha512-gvWSbgqP+569DdslUiCelxIv3IYK5Lgmq1UrRnk+s1WxQOQ16j3GPDcjdtgL5Au65DU/xQi6q3xPtf5Kta+3IQ== dependencies: - boom "7.x.x" + boom "0.4.x" crypto-browserify@^3.11.0: version "3.12.0" @@ -11632,11 +11542,6 @@ crypto-browserify@^3.11.0: randombytes "^2.0.0" randomfill "^1.0.3" -crypto-random-string@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" - integrity sha512-GsVpkFPlycH7/fRR7Dhcmnoii54gV1nz7y4CWyeFS14N+JVBBhY+r8amRHE4BwSYal7BPTDp8isvAlCxyFt3Hg== - crypto-random-string@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" @@ -11737,7 +11642,12 @@ css-url-regex@^1.1.0: resolved "https://registry.yarnpkg.com/css-url-regex/-/css-url-regex-1.1.0.tgz#83834230cc9f74c457de59eebd1543feeb83b7ec" integrity sha1-g4NCMMyfdMRX3lnuvRVD/uuDt+w= -css-what@^3.2.1, css-what@^5.0.0, css-what@^5.0.1: +css-what@^3.2.1: + version "3.4.2" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.4.2.tgz#ea7026fcb01777edbde52124e21f327e7ae950e4" + integrity sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ== + +css-what@^5.0.0, css-what@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/css-what/-/css-what-5.0.1.tgz#3efa820131f4669a8ac2408f9c32e7c7de9f4cad" integrity sha512-FYDTSHb/7KXsWICVsxdmiExPjCfRC4qRFBdVwv7Ax9hMnvMmEjP9RfxTEZ3qPZGmADDn2vAKSo9UcN1jKVYscg== @@ -11786,6 +11696,11 @@ csstype@^3.1.0: resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.1.tgz#841b532c45c758ee546a11d5bd7b7b473c8c30b9" integrity sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw== +ctype@0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/ctype/-/ctype-0.5.3.tgz#82c18c2461f74114ef16c135224ad0b9144ca12f" + integrity sha512-T6CEkoSV4q50zW3TlTHMbzy1E5+zlnNcY+yb7tWVYlTwPhx9LpnfAkd4wecpWknDyptp4k97LUZeInlf6jdzBg== + currently-unhandled@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" @@ -11884,13 +11799,6 @@ debug@2.6.9, debug@^2.1.0, debug@^2.1.1, debug@^2.1.3, debug@^2.2.0, debug@^2.3. dependencies: ms "2.0.0" -debug@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" - integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== - dependencies: - ms "2.0.0" - debug@4, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" @@ -11933,6 +11841,13 @@ decode-uri-component@^0.2.0: resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9" integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ== +decompress-response@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" + integrity sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA== + dependencies: + mimic-response "^1.0.0" + decompress-response@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" @@ -11972,6 +11887,11 @@ defaults@^1.0.3: dependencies: clone "^1.0.2" +defer-to-connect@^1.0.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" + integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== + defer-to-connect@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587" @@ -12011,6 +11931,11 @@ define-property@^2.0.2: is-descriptor "^1.0.2" isobject "^3.0.1" +delayed-stream@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-0.0.5.tgz#d4b1f43a93e8296dfe02694f4680bc37a313c73f" + integrity sha512-v+7uBd1pqe5YtgPacIIbZ8HuHeLFVNe4mUEyFDXL6KiqzEykjbw+5mXZXpGFgNVasdL4jWKgaKIXrEHiynN1LA== + delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -12078,11 +12003,6 @@ detect-indent@^6.0.0: resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-6.1.0.tgz#592485ebbbf6b3b1ab2be175c8393d04ca0d57e6" integrity sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA== -detect-indent@~5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d" - integrity sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g== - detect-libc@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" @@ -12093,11 +12013,6 @@ detect-newline@3.1.0, detect-newline@^3.0.0: resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== -detect-newline@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2" - integrity sha512-CwffZFvlJffUg9zZA0uqrjQayUTC8ob94pnr5sFwaVv3IOmkfUHcWH+jXaQK3askE51Cqe8/9Ql/0uXNwqZ8Zg== - detect-node@^2.0.4: version "2.1.0" resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" @@ -12127,14 +12042,6 @@ dezalgo@^1.0.0: asap "^2.0.0" wrappy "1" -dezalgo@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/dezalgo/-/dezalgo-1.0.4.tgz#751235260469084c132157dfa857f386d4c33d81" - integrity sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig== - dependencies: - asap "^2.0.0" - wrappy "1" - dialog-polyfill@^0.5.6: version "0.5.6" resolved "https://registry.yarnpkg.com/dialog-polyfill/-/dialog-polyfill-0.5.6.tgz#7507b4c745a82fcee0fa07ce64d835979719599a" @@ -12306,13 +12213,6 @@ dot-case@^3.0.4: no-case "^3.0.4" tslib "^2.0.3" -dot-prop@^4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.1.tgz#45884194a71fc2cda71cbb4bceb3a4dd2f433ba4" - integrity sha512-l0p4+mIuJIua0mhxGoh4a+iNL9bmeK5DvnSVQa6T0OhrVmaEa1XScX5Etc673FePCJOArq/4Pa2cLGODUWTPOQ== - dependencies: - is-obj "^1.0.0" - dot-prop@^5.2.0: version "5.3.0" resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88" @@ -12339,11 +12239,6 @@ dotenv-webpack@^1.8.0: dependencies: dotenv-defaults "^1.0.2" -dotenv@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-5.0.1.tgz#a5317459bd3d79ab88cff6e44057a6a3fbb1fcef" - integrity sha512-4As8uPrjfwb7VXC+WnLCbXK7y+Ueb2B3zgNCePYfhxS1PYeaO1YTeplffTEcbfLhvFNGLAz90VvJs9yomG7bow== - dotenv@^6.2.0: version "6.2.0" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-6.2.0.tgz#941c0410535d942c8becf28d3f357dbd9d476064" @@ -12365,6 +12260,11 @@ downshift@^6.0.15: react-is "^17.0.2" tslib "^2.3.0" +duplexer3@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.5.tgz#0b5e4d7bad5de8901ea4440624c8e1d20099217e" + integrity sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA== + duplexer@^0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" @@ -12406,11 +12306,6 @@ editions@^2.2.0: errlop "^2.0.0" semver "^6.3.0" -editor@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/editor/-/editor-1.0.0.tgz#60c7f87bd62bcc6a894fa8ccd6afb7823a24f742" - integrity sha512-SoRmbGStwNYHgKfjOrX2L0mUvp9bUVv0uPppZSOMAntEbcFtoC3MKF5b3T6HQPXKIV+QGY3xPO3JK5it5lVkuw== - ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" @@ -12481,6 +12376,11 @@ electron-rebuild@^3.2.6: tar "^6.0.5" yargs "^17.0.1" +electron-to-chromium@^1.3.564: + version "1.4.343" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.343.tgz#90f85c4c67aec42b3d076e597911b7b6a2d026fd" + integrity sha512-22C6pOljO+QQ/yeBZJkxewjsGwSKCXymng7dF8lir3m8iJGi6guoLVkK8jghCf3o0/tARFASAgLP8OzR9SKRCA== + electron-to-chromium@^1.4.284: version "1.4.305" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.305.tgz#e4dfe3e06ab783f33171f9bde9e8ed092510fcd0" @@ -12493,7 +12393,7 @@ element-resize-detector@^1.2.2: dependencies: batch-processor "1.0.0" -elliptic@^6.5.3, elliptic@~6.5.4: +elliptic@^6.5.3: version "6.5.4" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== @@ -14025,7 +13925,7 @@ ember-template-lint@^4.14.0: v8-compile-cache "^2.3.0" yargs "^17.5.1" -ember-template-recast@^6.0.0, ember-template-recast@^6.1.3: +ember-template-recast@^6.1.3: version "6.1.3" resolved "https://registry.yarnpkg.com/ember-template-recast/-/ember-template-recast-6.1.3.tgz#1e9b256ee9da24bcaa7c213088d01f32afc88001" integrity sha512-45lkfjrWlrMPlOd5rLFeQeePZwAvcS//x1x15kaiQTlqQdYWiYNXwbpWHqV+p9fXY6bEjl6EbyPhG/zBkgh8MA== @@ -14122,7 +14022,7 @@ encodeurl@^1.0.2, encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== -encoding@^0.1.11, encoding@^0.1.12: +encoding@^0.1.12: version "0.1.13" resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== @@ -14199,11 +14099,16 @@ entities@^2.0.0: resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== -entities@^3.0.1: +entities@^3.0.1, entities@~3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/entities/-/entities-3.0.1.tgz#2b887ca62585e96db3903482d336c1006c3001d4" integrity sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q== +entities@~1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" + integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== + entities@~2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/entities/-/entities-2.1.0.tgz#992d3129cf7df6870b96c57858c249a120f8b8b5" @@ -14219,11 +14124,6 @@ envinfo@^7.7.3: resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475" integrity sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw== -err-code@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/err-code/-/err-code-1.1.2.tgz#06e0116d3028f6aef4806849eb0ea6a748ae6960" - integrity sha512-CJAN+O0/yA1CKfRn9SXOGctSpEM7DCon/r/5r2eXFMY2zCCJBasFhcM5I+1kh3Ap11FsQCX+vGHceNPvpWKhoA== - err-code@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9" @@ -14385,18 +14285,6 @@ es6-map@^0.1.3: es6-symbol "~3.1.1" event-emitter "~0.3.5" -es6-promise@^4.0.3: - version "4.2.8" - resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" - integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== - -es6-promisify@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" - integrity sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ== - dependencies: - es6-promise "^4.0.3" - es6-set@~0.1.5: version "0.1.5" resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1" @@ -14439,7 +14327,7 @@ es6-weak-map@^2.0.1: es6-iterator "^2.0.3" es6-symbol "^3.1.1" -escalade@^3.1.1: +escalade@^3.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== @@ -14791,19 +14679,6 @@ exec-sh@^0.3.2, exec-sh@^0.3.4: resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.6.tgz#ff264f9e325519a60cb5e273692943483cca63bc" integrity sha512-nQn+hI3yp+oD0huYhKwvYI32+JFeq+XkNcD1GAo3Y/MjxsfVGmrrzrnzjWiNY6f+pUCP440fThsFh5gZrRAU/w== -execa@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" - integrity sha512-RztN09XglpYI7aBBrJCPW95jEH7YF1UEPOoX9yDhUTPdp7mK+CQvnLTuD10BNXZ3byLTu2uehZ8EcKT/4CGiFw== - dependencies: - cross-spawn "^5.0.1" - get-stream "^3.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - execa@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" @@ -15213,7 +15088,7 @@ fd-slicer@~1.1.0: dependencies: pend "~1.2.0" -figgy-pudding@^3.4.1, figgy-pudding@^3.5.1, figgy-pudding@^3.5.2: +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== @@ -15247,6 +15122,11 @@ file-loader@^6.2.0: loader-utils "^2.0.0" schema-utils "^3.0.0" +file-size@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/file-size/-/file-size-1.0.0.tgz#3338267d5d206bbf60f4df60c19d7ed3813a4657" + integrity sha512-tLIdonWTpABkU6Axg2yGChYdrOsy4V8xcm0IcyAP8fSsu6jiXLm5pgs083e4sq5fzNRZuAYolUbZyYmPvCKfwQ== + file-system-cache@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/file-system-cache/-/file-system-cache-1.0.5.tgz#84259b36a2bbb8d3d6eb1021d3132ffe64cfff4f" @@ -15312,11 +15192,6 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" -filter-obj@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/filter-obj/-/filter-obj-1.1.0.tgz#9b311112bc6c6127a16e016c6c5d7f19e0805c5b" - integrity sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ== - finalhandler@1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" @@ -15382,11 +15257,6 @@ find-node-modules@^2.1.2: findup-sync "^4.0.0" merge "^2.1.0" -find-npm-prefix@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/find-npm-prefix/-/find-npm-prefix-1.0.2.tgz#8d8ce2c78b3b4b9e66c8acc6a37c231eb841cfdf" - integrity sha512-KEftzJ+H90x6pcKtdXZEPsQse8/y/UnvzRKrOSQFprnrGaFuJ62fVkP34Iu2IYuMvyauCyoLTNkJZgrrGA2wkA== - find-root@1.1.0, find-root@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4" @@ -15555,7 +15425,7 @@ focus-trap@^6.7.1: dependencies: tabbable "^5.3.3" -follow-redirects@^1.0.0, follow-redirects@^1.14.8: +follow-redirects@^1.0.0: version "1.15.2" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== @@ -15570,6 +15440,11 @@ foreach@^2.0.4: resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.6.tgz#87bcc8a1a0e74000ff2bf9802110708cfb02eb6e" integrity sha512-k6GAGDyqLe9JaebCsFCoudPPWfihKu8pylYXRlqP1J7ms39iPoTtk2fviNglIeQEwdh0bQeKJ01ZPyuyQvKzwg== +forever-agent@~0.5.0: + version "0.5.2" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.5.2.tgz#6d0e09c4921f94a27f63d3b49c5feff1ea4c5130" + integrity sha512-PDG5Ef0Dob/JsZUxUltJOhm/Y9mlteAE+46y3M9RBz/Rd3QVENJ75aGRhN56yekTUboaBIkd8KVWX2NjF6+91A== + forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" @@ -15616,6 +15491,15 @@ form-data@^3.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +form-data@~0.1.0: + version "0.1.4" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-0.1.4.tgz#91abd788aba9702b1aabfa8bc01031a2ac9e3b12" + integrity sha512-x8eE+nzFtAMA0YYlSxf/Qhq6vP1f8wSoZ7Aw1GuctBcmudCNuTUmmx45TfEplyb6cjsZO/jvh6+1VpZn24ez+w== + dependencies: + async "~0.9.0" + combined-stream "~0.0.4" + mime "~1.2.11" + form-data@~2.3.2: version "2.3.3" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" @@ -15647,14 +15531,6 @@ fresh@0.5.2: resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== -from2@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/from2/-/from2-1.3.0.tgz#88413baaa5f9a597cfde9221d86986cd3c061dfd" - integrity sha512-1eKYoECvhpM4IT70THQV8XNfmZoIlnROymbwOSazfmQO3kK+zCV+LSqUDzl7gDo3MZddCFeVa9Zg3Hi6FXqcgg== - dependencies: - inherits "~2.0.1" - readable-stream "~1.1.10" - from2@^2.1.0: version "2.3.0" resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" @@ -15812,16 +15688,7 @@ fs-updater@^1.0.4: heimdalljs-logger "^0.1.9" rimraf "^2.6.2" -fs-vacuum@^1.2.10, fs-vacuum@~1.2.10: - version "1.2.10" - resolved "https://registry.yarnpkg.com/fs-vacuum/-/fs-vacuum-1.2.10.tgz#b7629bec07a4031a2548fdf99f5ecf1cc8b31e36" - integrity sha512-bwbv1FcWYwxN1F08I1THN8nS4Qe/pGq0gM8dy1J34vpxxp3qgZKJPPaqex36RyZO0sD2J+2ocnbwC2d/OjYICQ== - dependencies: - graceful-fs "^4.1.2" - path-is-inside "^1.0.1" - rimraf "^2.5.2" - -fs-write-stream-atomic@^1.0.8, fs-write-stream-atomic@~1.0.10: +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 sha1-tH31NJPvkR33VzHnCp3tAYnbQMk= @@ -15936,34 +15803,12 @@ gauge@~2.7.3: strip-ansi "^3.0.1" wide-align "^1.1.0" -genfun@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/genfun/-/genfun-5.0.0.tgz#9dd9710a06900a5c4a5bf57aca5da4e52fe76537" - integrity sha512-KGDOARWVga7+rnB3z9Sd2Letx515owfk0hSxHGuqjANb1M+x2bGZGqHLiozPsYMdM2OubeMni/Hpwmjq6qIUhA== - gensync@^1.0.0-beta.1, gensync@^1.0.0-beta.2: version "1.0.0-beta.2" resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== -gentle-fs@^2.3.0, gentle-fs@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/gentle-fs/-/gentle-fs-2.3.1.tgz#11201bf66c18f930ddca72cf69460bdfa05727b1" - integrity sha512-OlwBBwqCFPcjm33rF2BjW+Pr6/ll2741l+xooiwTCeaX2CA1ZuclavyMBe0/KlR21/XGsgY6hzEQZ15BdNa13Q== - dependencies: - aproba "^1.1.2" - chownr "^1.1.2" - cmd-shim "^3.0.3" - fs-vacuum "^1.2.10" - graceful-fs "^4.1.11" - iferr "^0.1.5" - infer-owner "^1.0.4" - mkdirp "^0.5.1" - path-is-inside "^1.0.2" - read-cmd-shim "^1.0.1" - slide "^1.1.6" - -get-caller-file@^2.0.1, get-caller-file@^2.0.5: +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== @@ -16023,11 +15868,6 @@ get-stdin@^9.0.0: resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-9.0.0.tgz#3983ff82e03d56f1b2ea0d3e60325f39d703a575" integrity sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA== -get-stream@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" - integrity sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ== - get-stream@^4.0.0, get-stream@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" @@ -16097,13 +15937,35 @@ glob-base@^0.3.0: glob-parent "^2.0.0" is-glob "^2.0.0" -glob-parent@^2.0.0, glob-parent@^3.1.0, glob-parent@^5.1.2, glob-parent@^6.0.1, glob-parent@~5.1.2: +glob-parent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" + integrity sha512-JDYOvfxio/t42HKdxkAYaCiBN7oYiuxykOxKxdaUW5Qn0zaYN3gRQWolrwdnf0shM9/EP0ebuuTmyoXNr1cC5w== + dependencies: + is-glob "^2.0.0" + +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: 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-parent@^6.0.1: + version "6.0.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== + dependencies: + is-glob "^4.0.3" + glob-promise@^3.4.0: version "3.4.0" resolved "https://registry.yarnpkg.com/glob-promise/-/glob-promise-3.4.0.tgz#b6b8f084504216f702dc2ce8c9bc9ac8866fdb20" @@ -16168,18 +16030,6 @@ glob@^7.2.0: once "^1.3.0" path-is-absolute "^1.0.0" -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-agent@^2.0.2: version "2.2.0" resolved "https://registry.yarnpkg.com/global-agent/-/global-agent-2.2.0.tgz#566331b0646e6bf79429a16877685c4a1fbf76dc" @@ -16193,7 +16043,7 @@ global-agent@^2.0.2: semver "^7.3.2" serialize-error "^7.0.1" -global-dirs@^0.1.0, global-dirs@^0.1.1: +global-dirs@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445" integrity sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg== @@ -16389,7 +16239,7 @@ good-listener@^1.2.2: dependencies: delegate "^3.1.2" -got@^11.7.0, got@^11.8.2, got@^11.8.5, got@^6.7.1, got@^9.6.0: +got@^11.7.0, got@^11.8.2: version "11.8.6" resolved "https://registry.yarnpkg.com/got/-/got-11.8.6.tgz#276e827ead8772eddbcfc97170590b841823233a" integrity sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g== @@ -16406,12 +16256,29 @@ got@^11.7.0, got@^11.8.2, got@^11.8.5, got@^6.7.1, got@^9.6.0: p-cancelable "^2.0.0" responselike "^2.0.0" +got@^9.6.0: + version "9.6.0" + resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" + integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q== + dependencies: + "@sindresorhus/is" "^0.14.0" + "@szmarczak/http-timer" "^1.1.2" + cacheable-request "^6.0.0" + decompress-response "^3.3.0" + duplexer3 "^0.1.4" + get-stream "^4.1.0" + lowercase-keys "^1.0.1" + mimic-response "^1.0.1" + p-cancelable "^1.0.0" + to-readable-stream "^1.0.0" + url-parse-lax "^3.0.0" + graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.4: version "4.2.8" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a" integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg== -graceful-fs@^4.2.10, graceful-fs@^4.2.2, graceful-fs@^4.2.6, graceful-fs@^4.2.9: +graceful-fs@^4.2.6, graceful-fs@^4.2.9: version "4.2.10" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== @@ -16527,7 +16394,7 @@ has-tostringtag@^1.0.0: dependencies: has-symbols "^1.0.2" -has-unicode@^2.0.0, has-unicode@^2.0.1, has-unicode@~2.0.1: +has-unicode@^2.0.0, has-unicode@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ== @@ -16672,15 +16539,15 @@ hastscript@^6.0.0: property-information "^5.0.0" space-separated-tokens "^1.0.0" -hawk@^9.0.1: - version "9.0.1" - resolved "https://registry.yarnpkg.com/hawk/-/hawk-9.0.1.tgz#0be51769103e76fe97a97ae7fa356c313bb93160" - integrity sha512-H2E+5ATFEXmorgVzYl3NzG3PCo2e+euYrHDnRpLLdOtJrQHGRXrJT9/joWnrkHCtzDZkaNoLXg/+TsSkD06eNg== +hawk@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/hawk/-/hawk-1.1.1.tgz#87cd491f9b46e4e2aeaca335416766885d2d1ed9" + integrity sha512-am8sVA2bCJIw8fuuVcKvmmNnGFUGW8spTkVtj2fXTEZVkfN42bwFZFtDem57eFi+NSxurJB8EQ7Jd3uCHLn8Vw== dependencies: - "@hapi/b64" "5.x.x" - "@hapi/boom" "9.x.x" - "@hapi/cryptiles" "5.x.x" - "@hapi/hoek" "9.x.x" + boom "0.4.x" + cryptiles "0.2.x" + hoek "0.9.x" + sntp "0.2.x" he@^1.2.0: version "1.2.0" @@ -16732,10 +16599,10 @@ hmac-drbg@^1.0.1: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.1" -hoek@6.x.x, hoek@~4.2.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.1.tgz#9634502aa12c445dd5a7c5734b572bb8738aacbb" - integrity sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA== +hoek@0.9.x: + version "0.9.1" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-0.9.1.tgz#3d322462badf07716ea7eb85baf88079cddce505" + integrity sha512-ZZ6eGyzGjyMTmpSPYVECXy9uNfqBR7x5CavhUaLOeD6W0vWK1mp/b7O3f86XE0Mtfo9rZ6Bh3fnuw9Xr8MF9zA== hoist-non-react-statics@^3.3.0: version "3.3.2" @@ -16759,13 +16626,25 @@ homedir-polyfill@^1.0.1: dependencies: parse-passwd "^1.0.0" -hosted-git-info@^2.1.4, hosted-git-info@^2.7.1, hosted-git-info@^2.8.9, hosted-git-info@^3.0.8, hosted-git-info@^4.0.1, hosted-git-info@^5.0.0: - version "3.0.8" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-3.0.8.tgz#6e35d4cc87af2c5f816e4cb9ce350ba87a3f370d" - integrity sha512-aXpmwoOhRBrw6X3j0h5RloK4x1OzsxMPyxqIHyNfSe2pypkVTZFpEiRoSipPEPlMrh0HW/XsjkJ5WgnCirpNUw== +hosted-git-info@^2.1.4: + version "2.8.9" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" + integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== + +hosted-git-info@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-4.1.0.tgz#827b82867e9ff1c8d0c4d9d53880397d2c86d224" + integrity sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA== dependencies: lru-cache "^6.0.0" +hosted-git-info@^5.0.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-5.2.1.tgz#0ba1c97178ef91f3ab30842ae63d6a272341156f" + integrity sha512-xIcQYMnhcx2Nr4JTjsFmwwnr9vldugPy9uVm0o87bjqqWMv9GaqsTeT+i99wTl0mk1uLxJtHxLb8kymqTENQsw== + dependencies: + lru-cache "^7.5.1" + html-encoding-sniffer@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3" @@ -16846,11 +16725,6 @@ htmlparser2@^7.2.0: domutils "^2.8.0" entities "^3.0.1" -http-cache-semantics@^3.8.1: - version "3.8.1" - resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2" - integrity sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w== - http-cache-semantics@^4.0.0, http-cache-semantics@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" @@ -16882,14 +16756,6 @@ http-parser-js@>=0.5.1: resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.3.tgz#01d2709c79d41698bb01d4decc5e9da4e4a033d9" integrity sha512-t7hjvef/5HEK7RWTdUzVUhl8zkEu+LlaE0IYzdMuvbSDipxBRpOn4Uhw8ZyECEa808iVT8XCjzo6xmYt4CiLZg== -http-proxy-agent@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405" - integrity sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg== - dependencies: - agent-base "4" - debug "3.1.0" - http-proxy-agent@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" @@ -16908,6 +16774,15 @@ http-proxy@^1.13.1, http-proxy@^1.18.1: follow-redirects "^1.0.0" requires-port "^1.0.0" +http-signature@~0.10.0: + version "0.10.1" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-0.10.1.tgz#4fbdac132559aa8323121e540779c0a012b27e66" + integrity sha512-coK8uR5rq2IMj+Hen+sKPA5ldgbCc1/spPdKCL1Fw6h+D0s/2LzMcRK0Cqufs1h0ryx/niwBHGFu8HC3hwU+lA== + dependencies: + asn1 "0.1.11" + assert-plus "^0.1.5" + ctype "0.5.3" + http-signature@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" @@ -16930,14 +16805,6 @@ https-browserify@^1.0.0: resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= -https-proxy-agent@^2.2.3: - version "2.2.4" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz#4ee7a737abd92678a293d9b34a1af4d0d08c787b" - integrity sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg== - dependencies: - agent-base "^4.3.0" - debug "^3.1.0" - https-proxy-agent@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz#702b71fb5520a132a66de1f67541d9e62154d82b" @@ -17024,7 +16891,7 @@ icss-utils@^5.0.0, icss-utils@^5.1.0: resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== -ieee754@^1.1.4: +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== @@ -17034,18 +16901,6 @@ iferr@^0.1.5: resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= -iferr@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/iferr/-/iferr-1.0.2.tgz#e9fde49a9da06dc4a4194c6c9ed6d08305037a6d" - integrity sha512-9AfeLfji44r5TKInjhz3W9DyZI1zR1JAf2hVBMGhddAKPqBsupb89jGfbCTHIGZd6fGZl9WlHdn4AObygyMKwg== - -ignore-walk@^3.0.1: - version "3.0.4" - resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.4.tgz#c9a09f69b7c7b479a5d74ac1a3c0d4236d2a6335" - integrity sha512-PY6Ii8o1jMRA1z4F2hRkH/xN59ox43DavKvD3oDpfurRlOJyAHpifIwpbdv1n4jt4ov0jSpw3kQ4GhJnpBL6WQ== - dependencies: - minimatch "^3.0.4" - ignore@^4.0.3, ignore@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" @@ -17061,10 +16916,10 @@ ignore@^5.2.0: resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== -immer@8.0.1, immer@^9.0.6: - version "9.0.19" - resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.19.tgz#67fb97310555690b5f9cd8380d38fc0aabb6b38b" - integrity sha512-eY+Y0qcsB4TZKwgQzLaE/lqYMlKhv5J9dyd2RhhtGhNo2njPXDqU9XPfcNfa3MIDsdtZt5KlkIsirlo4dHsWdQ== +immer@8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/immer/-/immer-8.0.1.tgz#9c73db683e2b3975c424fb0572af5889877ae656" + integrity sha512-aqXhGP7//Gui2+UrEtvxZxSquQVXTpZ7KDxfCcKAF3Vysvw0CViVaW9RZ1j1xlIYqaaaipBoqdqeibkc18PNvA== immutable@^4.0.0: version "4.1.0" @@ -17139,7 +16994,7 @@ inflection@^1.13.2, inflection@~1.13.1: resolved "https://registry.yarnpkg.com/inflection/-/inflection-1.13.4.tgz#65aa696c4e2da6225b148d7a154c449366633a32" integrity sha512-6I/HUDeYFfuNCVS3td055BaXBwKYuzw7K3ExVMStBowKo9oOAMJIXIHvdyR3iboTCp1b+1i5DSkIZTcwIktuDw== -inflight@^1.0.4, inflight@~1.0.6: +inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= @@ -17172,20 +17027,6 @@ ini@^1.3.4, ini@^1.3.5, ini@^1.3.8, ini@~1.3.0: resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== -init-package-json@^1.10.3: - version "1.10.3" - resolved "https://registry.yarnpkg.com/init-package-json/-/init-package-json-1.10.3.tgz#45ffe2f610a8ca134f2bd1db5637b235070f6cbe" - integrity sha512-zKSiXKhQveNteyhcj1CoOP8tqp1QuxPIPBl8Bid99DGLFqA1p87M6lNgfjJHSBoWJJlidGOv5rWjyYKEB3g2Jw== - dependencies: - glob "^7.1.1" - npm-package-arg "^4.0.0 || ^5.0.0 || ^6.0.0" - promzard "^0.3.0" - read "~1.0.1" - read-package-json "1 || 2" - semver "2.x || 3.x || 4 || 5" - validate-npm-package-license "^3.0.1" - validate-npm-package-name "^3.0.0" - inline-source-map-comment@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/inline-source-map-comment/-/inline-source-map-comment-1.0.5.tgz#50a8a44c2a790dfac441b5c94eccd5462635faf6" @@ -17281,21 +17122,11 @@ invariant@^2.2.2, invariant@^2.2.3, invariant@^2.2.4: dependencies: loose-envify "^1.0.0" -ip-regex@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" - integrity sha512-58yWmlHpp7VYfcdTwMTvwMmqx/Elfxjd9RXTDyMsbL7lLWmhMylLEqiYVLKuLzOZqVgiWXD9MfR62Vv89VRxkw== - -ip@1.1.5, ip@^1.1.5: +ip@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" integrity sha512-rBtCAQAJm8A110nbwn6YdveUnuZH3WrC36IwkRXxDnq53JvXA2NVQvB7IHyKomxK1MJ4VDNw3UtFDdXQ+AvLYA== -ip@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da" - integrity sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ== - ipaddr.js@1.9.1: version "1.9.1" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" @@ -17388,13 +17219,6 @@ is-callable@^1.1.4, is-callable@^1.2.3, is-callable@^1.2.4: resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w== -is-ci@^1.0.10: - version "1.2.1" - resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c" - integrity sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg== - dependencies: - ci-info "^1.5.0" - is-ci@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" @@ -17402,13 +17226,6 @@ is-ci@^2.0.0: dependencies: ci-info "^2.0.0" -is-cidr@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/is-cidr/-/is-cidr-3.1.1.tgz#e92ef121bdec2782271a77ce487a8b8df3718ab7" - integrity sha512-Gx+oErgq1j2jAKCR2Kbq0b3wbH0vQKqZ0wOlHxm0o56nq51Cs/DZA8oz9dMDhbHyHEGgJ86eTeVudtgMMOx3Mw== - dependencies: - cidr-regex "^2.0.10" - is-core-module@^2.2.0: version "2.5.0" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.5.0.tgz#f754843617c70bfd29b7bd87327400cda5c18491" @@ -17551,7 +17368,7 @@ is-glob@^2.0.0: dependencies: is-extglob "^1.0.0" -is-glob@^3.0.0: +is-glob@^3.0.0, is-glob@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= @@ -17577,14 +17394,6 @@ is-hexadecimal@^1.0.0: resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz#cc35c97588da4bd49a8eedd6bc4082d44dcb23a7" integrity sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw== -is-installed-globally@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.1.0.tgz#0dfd98f5a9111716dd535dda6492f67bf3d25a80" - integrity sha512-ERNhMg+i/XgDwPIPF3u24qpajVreaiSuvpb1Uu0jugw7KKcxGyCX8cgp8P5fwTmAuXku6beDHHECdKArjlg7tw== - dependencies: - global-dirs "^0.1.0" - is-path-inside "^1.0.0" - 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" @@ -17620,11 +17429,6 @@ is-negative-zero@^2.0.1: resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24" integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w== -is-npm@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" - integrity sha512-9r39FIr3d+KD9SbX0sfMsHzb5PP3uimOiwr3YupUaUFG4W0l1U57Rx3utpttV7qz5U3jmrO5auUa04LU9pyHsg== - is-npm@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-5.0.0.tgz#43e8d65cc56e1b67f8d47262cf667099193f45a8" @@ -17649,11 +17453,6 @@ is-number@^7.0.0: resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== -is-obj@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" - integrity sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg== - is-obj@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" @@ -17664,13 +17463,6 @@ is-object@^1.0.1: resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.2.tgz#a56552e1c665c9e950b4a025461da87e72f86fcf" integrity sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA== -is-path-inside@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" - integrity sha512-qhsCR/Esx4U4hg/9I19OVUAJkGWtjRYHMRgUMZE2TDdj+Ag+kttZanLupfddNyglzz50cUlmWzUaI37GDfNx/g== - dependencies: - path-is-inside "^1.0.1" - 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" @@ -17691,7 +17483,7 @@ is-plain-object@5.0.0, is-plain-object@^5.0.0: resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== -is-plain-object@^2.0.4: +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== @@ -17703,11 +17495,6 @@ is-potential-custom-element-name@^1.0.1: resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== -is-primitive@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-3.0.1.tgz#98c4db1abff185485a657fc2905052b940524d05" - integrity sha512-GljRxhWvlCNRfZyORiH77FwdFwGcMO620o37EOYC0ORWdq+WYNVqW0w2Juzew4M+L81l6/QS3t5gkkihyRqv9w== - is-reference@^1.1.0: version "1.2.1" resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-1.2.1.tgz#8b2dac0b371f4bc994fdeaba9eb542d03002d0b7" @@ -18456,7 +18243,7 @@ jest@^27.4.7: import-local "^3.0.2" jest-cli "^27.4.7" -jpeg-js@^0.4.2, jpeg-js@^0.4.4: +jpeg-js@^0.4.2: version "0.4.4" resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.4.4.tgz#a9f1c6f1f9f0fa80cdb3484ed9635054d28936aa" integrity sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg== @@ -18616,12 +18403,17 @@ json-api-serializer@^2.6.0: dependencies: setimmediate "^1.0.5" +json-buffer@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" + integrity sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ== + json-buffer@3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== -json-parse-better-errors@^1.0.0, json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: +json-parse-better-errors@^1.0.1, 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== @@ -18648,10 +18440,10 @@ json-schema-traverse@^1.0.0: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== -json-schema@0.2.3, 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-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + integrity sha512-a3xHnILGMtk+hDOqNwHzF6e2fNbiMrXZvxKQiEv2MlgQP+pjIOzqAmKYD2mDpXYE/44M7g+n9p2bKkYWDUcXCQ== json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" @@ -18665,7 +18457,7 @@ json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1: dependencies: jsonify "~0.0.0" -json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: +json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.0, 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 sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= @@ -18675,6 +18467,13 @@ json5@^0.5.1: resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= +json5@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593" + integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA== + dependencies: + minimist "^1.2.0" + json5@^2.1.2, json5@^2.1.3, json5@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" @@ -18716,16 +18515,6 @@ jsonlint@^1.6.3: JSV "^4.0.x" nomnom "^1.5.x" -jsonparse@^1.2.0, jsonparse@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" - integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg== - -jsonpointer@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-5.0.0.tgz#f802669a524ec4805fa7389eadbc9921d5dc8072" - integrity sha512-PNYZIdMjVIvVgDSYKTT63Y+KZ6IZvGRNNWcxwD+GNnUz1MKPfv30J8ueCjdwcN0nDx2SlshgyB7Oy0epAzVRRg== - jsprim@^1.2.2: version "1.4.1" resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" @@ -18746,6 +18535,13 @@ just-extend@^4.0.2: resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-4.2.1.tgz#ef5e589afb61e5d66b24eca749409a8939a8c744" integrity sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg== +keyv@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" + integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA== + dependencies: + json-buffer "3.0.0" + keyv@^4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.0.3.tgz#4f3aa98de254803cafcd2896734108daa35e4254" @@ -18811,13 +18607,6 @@ language-tags@^1.0.5: dependencies: language-subtag-registry "~0.3.2" -latest-version@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-3.1.0.tgz#a205383fea322b33b5ae3b18abee0dc2f356ee15" - integrity sha512-Be1YRHWWlZaSsrz2U+VInk+tO0EwLIyV+23RhWLINJYwg/UIikxjlj3MhH37/6/EDCAusjajvMkMMUXRaMWl/w== - dependencies: - package-json "^4.0.0" - latest-version@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-5.1.0.tgz#119dfe908fe38d15dfa43ecd13fa12ec8832face" @@ -18825,11 +18614,6 @@ latest-version@^5.1.0: dependencies: package-json "^6.3.0" -lazy-property@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lazy-property/-/lazy-property-1.0.0.tgz#84ddc4b370679ba8bd4cdcfa4c06b43d57111147" - integrity sha512-O52TK7FHpBPzdtvc5GoF0EPLQIBMqrAupANPGBidPkrDpl9IXlzuma3T+m0o0OpkRVPmTu3SDoT7985lw4KbNQ== - lazy-universal-dotenv@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/lazy-universal-dotenv/-/lazy-universal-dotenv-3.0.1.tgz#a6c8938414bca426ab8c9463940da451a911db38" @@ -18871,140 +18655,6 @@ levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" -libcipm@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/libcipm/-/libcipm-4.0.8.tgz#dcea4919e10dfbce420327e63901613b9141bc89" - integrity sha512-IN3hh2yDJQtZZ5paSV4fbvJg4aHxCCg5tcZID/dSVlTuUiWktsgaldVljJv6Z5OUlYspx6xQkbR0efNodnIrOA== - dependencies: - bin-links "^1.1.2" - bluebird "^3.5.1" - figgy-pudding "^3.5.1" - find-npm-prefix "^1.0.2" - graceful-fs "^4.1.11" - ini "^1.3.5" - lock-verify "^2.1.0" - mkdirp "^0.5.1" - npm-lifecycle "^3.0.0" - npm-logical-tree "^1.2.1" - npm-package-arg "^6.1.0" - pacote "^9.1.0" - read-package-json "^2.0.13" - rimraf "^2.6.2" - worker-farm "^1.6.0" - -libnpm@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/libnpm/-/libnpm-3.0.1.tgz#0be11b4c9dd4d1ffd7d95c786e92e55d65be77a2" - integrity sha512-d7jU5ZcMiTfBqTUJVZ3xid44fE5ERBm9vBnmhp2ECD2Ls+FNXWxHSkO7gtvrnbLO78gwPdNPz1HpsF3W4rjkBQ== - dependencies: - bin-links "^1.1.2" - bluebird "^3.5.3" - find-npm-prefix "^1.0.2" - libnpmaccess "^3.0.2" - libnpmconfig "^1.2.1" - libnpmhook "^5.0.3" - libnpmorg "^1.0.1" - libnpmpublish "^1.1.2" - libnpmsearch "^2.0.2" - libnpmteam "^1.0.2" - lock-verify "^2.0.2" - npm-lifecycle "^3.0.0" - npm-logical-tree "^1.2.1" - npm-package-arg "^6.1.0" - npm-profile "^4.0.2" - npm-registry-fetch "^4.0.0" - npmlog "^4.1.2" - pacote "^9.5.3" - read-package-json "^2.0.13" - stringify-package "^1.0.0" - -libnpmaccess@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/libnpmaccess/-/libnpmaccess-3.0.2.tgz#8b2d72345ba3bef90d3b4f694edd5c0417f58923" - integrity sha512-01512AK7MqByrI2mfC7h5j8N9V4I7MHJuk9buo8Gv+5QgThpOgpjB7sQBDDkeZqRteFb1QM/6YNdHfG7cDvfAQ== - dependencies: - aproba "^2.0.0" - get-stream "^4.0.0" - npm-package-arg "^6.1.0" - npm-registry-fetch "^4.0.0" - -libnpmconfig@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/libnpmconfig/-/libnpmconfig-1.2.1.tgz#c0c2f793a74e67d4825e5039e7a02a0044dfcbc0" - integrity sha512-9esX8rTQAHqarx6qeZqmGQKBNZR5OIbl/Ayr0qQDy3oXja2iFVQQI81R6GZ2a02bSNZ9p3YOGX1O6HHCb1X7kA== - dependencies: - figgy-pudding "^3.5.1" - find-up "^3.0.0" - ini "^1.3.5" - -libnpmhook@^5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/libnpmhook/-/libnpmhook-5.0.3.tgz#4020c0f5edbf08ebe395325caa5ea01885b928f7" - integrity sha512-UdNLMuefVZra/wbnBXECZPefHMGsVDTq5zaM/LgKNE9Keyl5YXQTnGAzEo+nFOpdRqTWI9LYi4ApqF9uVCCtuA== - dependencies: - aproba "^2.0.0" - figgy-pudding "^3.4.1" - get-stream "^4.0.0" - npm-registry-fetch "^4.0.0" - -libnpmorg@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/libnpmorg/-/libnpmorg-1.0.1.tgz#5d2503f6ceb57f33dbdcc718e6698fea6d5ad087" - integrity sha512-0sRUXLh+PLBgZmARvthhYXQAWn0fOsa6T5l3JSe2n9vKG/lCVK4nuG7pDsa7uMq+uTt2epdPK+a2g6btcY11Ww== - dependencies: - aproba "^2.0.0" - figgy-pudding "^3.4.1" - get-stream "^4.0.0" - npm-registry-fetch "^4.0.0" - -libnpmpublish@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/libnpmpublish/-/libnpmpublish-1.1.3.tgz#e3782796722d79eef1a0a22944c117e0c4ca4280" - integrity sha512-/3LsYqVc52cHXBmu26+J8Ed7sLs/hgGVFMH1mwYpL7Qaynb9RenpKqIKu0sJ130FB9PMkpMlWjlbtU8A4m7CQw== - dependencies: - aproba "^2.0.0" - figgy-pudding "^3.5.1" - get-stream "^4.0.0" - lodash.clonedeep "^4.5.0" - normalize-package-data "^2.4.0" - npm-package-arg "^6.1.0" - npm-registry-fetch "^4.0.0" - semver "^5.5.1" - ssri "^6.0.1" - -libnpmsearch@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/libnpmsearch/-/libnpmsearch-2.0.2.tgz#9a4f059102d38e3dd44085bdbfe5095f2a5044cf" - integrity sha512-VTBbV55Q6fRzTdzziYCr64+f8AopQ1YZ+BdPOv16UegIEaE8C0Kch01wo4s3kRTFV64P121WZJwgmBwrq68zYg== - dependencies: - figgy-pudding "^3.5.1" - get-stream "^4.0.0" - npm-registry-fetch "^4.0.0" - -libnpmteam@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/libnpmteam/-/libnpmteam-1.0.2.tgz#8b48bcbb6ce70dd8150c950fcbdbf3feb6eec820" - integrity sha512-p420vM28Us04NAcg1rzgGW63LMM6rwe+6rtZpfDxCcXxM0zUTLl7nPFEnRF3JfFBF5skF/yuZDUthTsHgde8QA== - dependencies: - aproba "^2.0.0" - figgy-pudding "^3.4.1" - get-stream "^4.0.0" - npm-registry-fetch "^4.0.0" - -libnpx@^10.2.4: - version "10.2.4" - resolved "https://registry.yarnpkg.com/libnpx/-/libnpx-10.2.4.tgz#ef0e3258e29aef2ec7ee3276115e20e67f67d4ee" - integrity sha512-BPc0D1cOjBeS8VIBKUu5F80s6njm0wbVt7CsGMrIcJ+SI7pi7V0uVPGpEMH9H5L8csOcclTxAXFE2VAsJXUhfA== - dependencies: - dotenv "^5.0.1" - npm-package-arg "^6.0.0" - rimraf "^2.6.2" - safe-buffer "^5.1.0" - update-notifier "^2.3.0" - which "^1.3.0" - y18n "^4.0.0" - yargs "^14.2.3" - license-checker@^25.0.1: version "25.0.1" resolved "https://registry.yarnpkg.com/license-checker/-/license-checker-25.0.1.tgz#4d14504478a5240a857bb3c21cd0491a00d761fa" @@ -19044,6 +18694,13 @@ lines-and-columns@^1.1.6: resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= +linkify-it@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-2.2.0.tgz#e3b54697e78bf915c70a38acd78fd09e0058b1cf" + integrity sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw== + dependencies: + uc.micro "^1.0.1" + linkify-it@^3.0.1: version "3.0.2" resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-3.0.2.tgz#f55eeb8bc1d3ae754049e124ab3bb56d97797fb8" @@ -19051,6 +18708,20 @@ linkify-it@^3.0.1: dependencies: uc.micro "^1.0.1" +linkify-it@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-4.0.1.tgz#01f1d5e508190d06669982ba31a7d9f56a5751ec" + integrity sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw== + dependencies: + uc.micro "^1.0.1" + +linkify-it@~1.2.0: + version "1.2.4" + resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-1.2.4.tgz#0773526c317c8fd13bd534ee1d180ff88abf881a" + integrity sha512-eGHwtlABkp1NOJSiKUNqBf3SYAS5jPHtvRXPAgNaQwTqmkTahjtiLH9NtxdR5IOPhNvwNMN/diswSfZKzUkhGg== + dependencies: + uc.micro "^1.0.1" + lint-staged@^13.0.2: version "13.0.2" resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-13.0.2.tgz#35a1c57130e9ad5b1dea784972a40777ba433dd5" @@ -19130,7 +18801,25 @@ loader-runner@^4.2.0: resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.2.0.tgz#d7022380d66d14c5fb1d496b89864ebcfd478384" integrity sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw== -loader-utils@2.0.0, loader-utils@^1.2.3, loader-utils@^1.4.0, loader-utils@^2.0.0, loader-utils@^2.0.4: +loader-utils@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.0.tgz#e4cace5b816d425a166b5f097e10cd12b36064b0" + integrity sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^2.1.2" + +loader-utils@^1.2.3, loader-utils@^1.4.0: + version "1.4.2" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.2.tgz#29a957f3a63973883eb684f10ffd3d151fec01a3" + integrity sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^1.0.1" + +loader-utils@^2.0.0: version "2.0.4" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c" integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw== @@ -19191,22 +18880,6 @@ locate-path@^7.1.0: dependencies: p-locate "^6.0.0" -lock-verify@^2.0.2, lock-verify@^2.1.0, lock-verify@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/lock-verify/-/lock-verify-2.2.2.tgz#9e93c0999dc3cbbede4f16f9cfdaa93ead8c76ef" - integrity sha512-2CUNtr1ZSVKJHcYP8uEzafmmuyauCB5zZimj8TvQd/Lflt9kXVZs+8S+EbAzZLaVUDn8CYGmeC3DFGdYfnCzeQ== - dependencies: - "@iarna/cli" "^2.1.0" - npm-package-arg "^6.1.0" - semver "^5.4.1" - -lockfile@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/lockfile/-/lockfile-1.0.4.tgz#07f819d25ae48f87e538e6578b6964a4981a5609" - integrity sha512-cvbTwETRfsFh4nHsL1eGWapU1XFi5Ot9E85sWAwia7Y7EgB7vfqcZhTKZ+l7hCGxSPoushMv5GKhT5PdLv03WA== - dependencies: - signal-exit "^3.0.2" - lodash-es@^4.17.11: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee" @@ -19233,14 +18906,6 @@ lodash._baseflatten@^3.0.0: lodash.isarguments "^3.0.0" lodash.isarray "^3.0.0" -lodash._baseuniq@~4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash._baseuniq/-/lodash._baseuniq-4.6.0.tgz#0ebb44e456814af7905c6212fa2c9b2d51b841e8" - integrity sha512-Ja1YevpHZctlI5beLA7oc5KNDhGcPixFhcqSiORHNsp/1QTv7amAXzw+gu4YOvErqVlMVyIJGgtzeepCnnur0A== - dependencies: - lodash._createset "~4.0.0" - lodash._root "~3.0.0" - lodash._bindcallback@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz#e531c27644cf8b57a99e17ed95b35c748789392e" @@ -19255,11 +18920,6 @@ lodash._createassigner@^3.0.0: lodash._isiterateecall "^3.0.0" lodash.restparam "^3.0.0" -lodash._createset@~4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/lodash._createset/-/lodash._createset-4.0.3.tgz#0f4659fbb09d75194fa9e2b88a6644d363c9fe26" - integrity sha512-GTkC6YMprrJZCYU3zcqZj+jkXkrXzq3IPBcF/fIPpNEAB4hZEtXU8zp/RwKOvZl43NUmwDbyRk3+ZTbeRdEBXA== - lodash._getnative@^3.0.0: version "3.9.1" resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" @@ -19275,11 +18935,6 @@ lodash._reinterpolate@^3.0.0: resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= -lodash._root@~3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/lodash._root/-/lodash._root-3.0.1.tgz#fba1c4524c19ee9a5f8136b4609f017cf4ded692" - integrity sha512-O0pWuFSK6x4EXhM1dhZ8gchNtG7JMqBtrHdoUFUWXD7dJnNSUze1GuyQr5sOs0aCvgGeI3o/OJW8f4ca7FDxmQ== - lodash.assign@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-3.2.0.tgz#3ce9f0234b4b2223e296b8fa0ac1fee8ebca64fa" @@ -19309,7 +18964,7 @@ lodash.castarray@^4.4.0: resolved "https://registry.yarnpkg.com/lodash.castarray/-/lodash.castarray-4.4.0.tgz#c02513515e309daddd4c24c60cfddcf5976d9115" integrity sha1-wCUTUV4wna3dTCTGDP3c9ZdtkRU= -lodash.clonedeep@^4.4.1, lodash.clonedeep@^4.5.0, lodash.clonedeep@~4.5.0: +lodash.clonedeep@^4.4.1, lodash.clonedeep@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" integrity sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ== @@ -19503,12 +19158,7 @@ lodash.truncate@^4.4.2: resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM= -lodash.union@~4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.union/-/lodash.union-4.6.0.tgz#48bb5088409f16f1821666641c44dd1aaae3cd88" - integrity sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw== - -lodash.uniq@4.5.0, lodash.uniq@^4.2.0, lodash.uniq@^4.5.0, lodash.uniq@~4.5.0: +lodash.uniq@4.5.0, lodash.uniq@^4.2.0, lodash.uniq@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" integrity sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ== @@ -19523,11 +19173,6 @@ lodash.values@^4.3.0: resolved "https://registry.yarnpkg.com/lodash.values/-/lodash.values-4.3.0.tgz#a3a6c2b0ebecc5c2cba1c17e6e620fe81b53d347" integrity sha512-r0RwvdCv8id9TUblb/O7rYPwVy6lerCbcawrfdo9iC/1t1wsNMJknO79WNBgwkH0hIeJ08jmvvESbFpNb4jH0Q== -lodash.without@~4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.without/-/lodash.without-4.4.0.tgz#3cd4574a00b67bae373a94b748772640507b7aac" - integrity sha512-M3MefBwfDhgKgINVuBJCO1YR3+gf6s9HNJsIiZ/Ru77Ws6uTb9eBuvrkpzO+9iLoAaRodGuq7tyrPCx+74QYGQ== - lodash@^4.17.10, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4, lodash@^4.7.0: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" @@ -19590,6 +19235,11 @@ lower-case@^2.0.2: dependencies: tslib "^2.0.3" +lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" + integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== + lowercase-keys@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" @@ -19603,14 +19253,6 @@ lowlight@^1.14.0, lowlight@^1.17.0: fault "^1.0.0" highlight.js "~10.7.0" -lru-cache@^4.0.1: - 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" @@ -19625,7 +19267,12 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" -lzma-native@^8.0.5, lzma-native@^8.0.6: +lru-cache@^7.5.1: + version "7.18.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.18.3.tgz#f793896e0fd0e954a59dfdd82f0773808df6aa89" + integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA== + +lzma-native@^8.0.5: version "8.0.6" resolved "https://registry.yarnpkg.com/lzma-native/-/lzma-native-8.0.6.tgz#3ea456209d643bafd9b5d911781bdf0b396b2665" integrity sha512-09xfg67mkL2Lz20PrrDeNYZxzeW7ADtpYFbwSQh9U8+76RIzx5QsJBMy8qikv3hbUPfpy6hqwxt6FcGK81g9AA== @@ -19648,13 +19295,6 @@ magic-string@^0.25.7: dependencies: sourcemap-codec "^1.4.4" -make-dir@^1.0.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" - integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== - dependencies: - pify "^3.0.0" - make-dir@^2.0.0, make-dir@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" @@ -19670,44 +19310,6 @@ make-dir@^3.0.0, make-dir@^3.0.2, make-dir@^3.1.0: dependencies: semver "^6.0.0" -make-fetch-happen@^5.0.0: - version "5.0.2" - resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-5.0.2.tgz#aa8387104f2687edca01c8687ee45013d02d19bd" - integrity sha512-07JHC0r1ykIoruKO8ifMXu+xEU8qOXDFETylktdug6vJDACnP+HKevOu3PXyNPzFyTSlz8vrBYlBO1JZRe8Cag== - dependencies: - agentkeepalive "^3.4.1" - cacache "^12.0.0" - http-cache-semantics "^3.8.1" - http-proxy-agent "^2.1.0" - https-proxy-agent "^2.2.3" - lru-cache "^5.1.1" - mississippi "^3.0.0" - node-fetch-npm "^2.0.2" - promise-retry "^1.1.1" - socks-proxy-agent "^4.0.0" - ssri "^6.0.0" - -make-fetch-happen@^8.0.9: - version "8.0.14" - resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-8.0.14.tgz#aaba73ae0ab5586ad8eaa68bd83332669393e222" - integrity sha512-EsS89h6l4vbfJEtBZnENTOFk8mCRpY5ru36Xe5bcX1KYIli2mkSHqoFsp5O1wMDvTJJzxe/4THpCTtygjeeGWQ== - dependencies: - agentkeepalive "^4.1.3" - cacache "^15.0.5" - http-cache-semantics "^4.1.0" - http-proxy-agent "^4.0.1" - https-proxy-agent "^5.0.0" - is-lambda "^1.0.1" - lru-cache "^6.0.0" - minipass "^3.1.3" - minipass-collect "^1.0.2" - minipass-fetch "^1.3.2" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.4" - promise-retry "^2.0.1" - socks-proxy-agent "^5.0.0" - ssri "^8.0.0" - make-fetch-happen@^9.1.0: version "9.1.0" resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz#53085a09e7971433e6765f7971bf63f4e05cb968" @@ -19792,7 +19394,7 @@ markdown-it-terminal@0.2.1: lodash.merge "^4.6.2" markdown-it "^8.3.1" -markdown-it@^12.2.0, markdown-it@^12.3.2, markdown-it@^13.0.1, markdown-it@^4.3.0, markdown-it@^8.3.1: +markdown-it@^12.2.0: version "12.3.2" resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-12.3.2.tgz#bf92ac92283fe983fe4de8ff8abfb5ad72cd0c90" integrity sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg== @@ -19803,6 +19405,39 @@ markdown-it@^12.2.0, markdown-it@^12.3.2, markdown-it@^13.0.1, markdown-it@^4.3. mdurl "^1.0.1" uc.micro "^1.0.5" +markdown-it@^13.0.1: + version "13.0.1" + resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-13.0.1.tgz#c6ecc431cacf1a5da531423fc6a42807814af430" + integrity sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q== + dependencies: + argparse "^2.0.1" + entities "~3.0.1" + linkify-it "^4.0.1" + mdurl "^1.0.1" + uc.micro "^1.0.5" + +markdown-it@^4.3.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-4.4.0.tgz#3df373dbea587a9a7fef3e56311b68908f75c414" + integrity sha512-Rl8dHHeLuAh3E72OPY0tY7CLvlxgHiLhlshIYswAAabAg4YDBLa6e/LTgNkkxBO2K61ESzoquPQFMw/iMrT1PA== + dependencies: + argparse "~1.0.2" + entities "~1.1.1" + linkify-it "~1.2.0" + mdurl "~1.0.0" + uc.micro "^1.0.0" + +markdown-it@^8.3.1: + version "8.4.2" + resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-8.4.2.tgz#386f98998dc15a37722aa7722084f4020bdd9b54" + integrity sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ== + dependencies: + argparse "^1.0.7" + entities "~1.1.1" + linkify-it "^2.0.0" + mdurl "^1.0.1" + uc.micro "^1.0.5" + markdown-table@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/markdown-table/-/markdown-table-2.0.0.tgz#194a90ced26d31fe753d8b9434430214c011865b" @@ -20006,22 +19641,17 @@ mdn-links@^0.1.0: resolved "https://registry.yarnpkg.com/mdn-links/-/mdn-links-0.1.0.tgz#e24c83b97cb4c5886cc39f2f780705fbfe273aa5" integrity sha1-4kyDuXy0xYhsw58veAcF+/4nOqU= -mdurl@^1.0.0, mdurl@^1.0.1: +mdurl@^1.0.0, mdurl@^1.0.1, mdurl@~1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" integrity sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4= -meant@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/meant/-/meant-1.0.3.tgz#67769af9de1d158773e928ae82c456114903554c" - integrity sha512-88ZRGcNxAq4EH38cQ4D85PM57pikCwS8Z99EWHODxN7KBY+UuPiqzRTtZzS8KTXO/ywSWbdjjJST2Hly/EQxLw== - 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== -mem@^4.0.0, mem@^4.3.0: +mem@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178" integrity sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w== @@ -20283,6 +19913,11 @@ mime-types@^2.1.25: dependencies: mime-db "1.50.0" +mime-types@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-1.0.2.tgz#995ae1392ab8affcbfcb2641dd054e943c0d5dce" + integrity sha512-echfutj/t5SoTL4WZpqjA1DCud1XO0WQF3/GJ48YBmc4ZMhCK77QA6Z/w6VTQERLKuJ4drze3kw2TUT8xZXVNw== + 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" @@ -20300,6 +19935,11 @@ mime@^2.0.3, mime@^2.4.4, mime@^2.4.6: resolved "https://registry.yarnpkg.com/mime/-/mime-2.5.2.tgz#6e3dc6cc2b9510643830e5f19d5cb753da5eeabe" integrity sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg== +mime@~1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.2.11.tgz#58203eed86e3a5ef17aed2b7d9ebd47f0a60dd10" + integrity sha512-Ysa2F/nqTNGHhhm9MV8ure4+Hc+Y8AWiqUdHxsO7xu8zc92ND9f3kpALHjaP026Ft17UfxrMt95c50PLUeynBw== + mimic-fn@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" @@ -20315,7 +19955,7 @@ mimic-fn@^4.0.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-4.0.0.tgz#60a90550d5cb0b239cca65d893b1a53b29871ecc" integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== -mimic-response@^1.0.0: +mimic-response@^1.0.0, mimic-response@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== @@ -20354,13 +19994,20 @@ minimalistic-crypto-utils@^1.0.1: resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= -"minimatch@2 || 3", minimatch@3.0.4, minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: +"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.4, minimatch@^3.1.2: 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" +minimatch@3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + minimatch@^5.0.1: version "5.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.2.tgz#0939d7d6f0898acbd1508abe534d1929368a8fff" @@ -20384,7 +20031,17 @@ minimist-options@4.1.0: is-plain-obj "^1.1.0" kind-of "^6.0.3" -minimist@1.2.5, minimist@^0.2.1, minimist@^1.1.0, minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6: +minimist@1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + +minimist@^0.2.1: + version "0.2.4" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.2.4.tgz#0085d5501e29033748a2f2a4da0180142697a475" + integrity sha512-Pkrrm8NjyQ8yVt8Am9M+yUt74zE3iokhzbG1bFVNjLB92vwM71hf40RkEsryg98BujhVOncKm/C1xROxZ030LQ== + +minimist@^1.1.0, minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6: version "1.2.6" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== @@ -20396,7 +20053,7 @@ minipass-collect@^1.0.2: dependencies: minipass "^3.0.0" -minipass-fetch@^1.3.0, minipass-fetch@^1.3.2: +minipass-fetch@^1.3.2: version "1.4.1" resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-1.4.1.tgz#d75e0091daac1b0ffd7e9d41629faff7d0c1f1b6" integrity sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw== @@ -20414,14 +20071,6 @@ minipass-flush@^1.0.5: dependencies: minipass "^3.0.0" -minipass-json-stream@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minipass-json-stream/-/minipass-json-stream-1.0.1.tgz#7edbb92588fbfc2ff1db2fc10397acb7b6b44aa7" - integrity sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg== - dependencies: - jsonparse "^1.3.1" - minipass "^3.0.0" - minipass-pipeline@^1.2.2, minipass-pipeline@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz#68472f79711c084657c067c5c6ad93cddea8214c" @@ -20436,7 +20085,7 @@ minipass-sized@^1.0.3: dependencies: minipass "^3.0.0" -minipass@^2.2.0, minipass@^2.3.5: +minipass@^2.2.0: version "2.9.0" resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== @@ -20541,7 +20190,7 @@ mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.4, mkdirp@^0.5.5, mkdir dependencies: minimist "^1.2.5" -mkdirp@^0.5.6, mkdirp@~0.5.0: +mkdirp@^0.5.6: version "0.5.6" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== @@ -20574,7 +20223,7 @@ morgan@^1.10.0: on-finished "~2.3.0" on-headers "~1.0.2" -mout@^1.0.0, mout@^1.2.4: +mout@^1.0.0: version "1.2.4" resolved "https://registry.yarnpkg.com/mout/-/mout-1.2.4.tgz#9ffd261c4d6509e7ebcbf6b641a89b36ecdf8155" integrity sha512-mZb9uOruMWgn/fw28DG4/yE3Kehfk1zKCLhuDU2O3vlKdnBBr4XaOCqVTflJ5aODavGUPqFHZgrFX3NJVuxGhQ== @@ -20621,7 +20270,7 @@ mute-stream@0.0.7: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= -mute-stream@0.0.8, mute-stream@~0.0.4: +mute-stream@0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== @@ -20631,7 +20280,7 @@ nan@^2.12.1: resolved "https://registry.yarnpkg.com/nan/-/nan-2.15.0.tgz#3f34a473ff18e15c1b5626b62903b5ad6e665fee" integrity sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ== -nanoid@^3.1.31, nanoid@^3.3.4: +nanoid@^3.3.4: version "3.3.4" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab" integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw== @@ -20733,16 +20382,7 @@ node-dir@^0.1.17: dependencies: minimatch "^3.0.2" -node-fetch-npm@^2.0.2: - version "2.0.4" - resolved "https://registry.yarnpkg.com/node-fetch-npm/-/node-fetch-npm-2.0.4.tgz#6507d0e17a9ec0be3bec516958a497cec54bf5a4" - integrity sha512-iOuIQDWDyjhv9qSDrj9aq/klt6F9z1p2otB3AV7v3zBDcL/x+OfGsvGQZZCcMZbUf4Ujw1xGNQkjvGnVT22cKg== - dependencies: - encoding "^0.1.11" - json-parse-better-errors "^1.0.0" - safe-buffer "^5.1.1" - -node-fetch@^2.6.0, node-fetch@^2.6.1, node-fetch@^2.6.7: +node-fetch@^2.6.0, node-fetch@^2.6.1: version "2.6.9" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.9.tgz#7c7f744b5cc6eb5fd404e0c7a9fec630a55657e6" integrity sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg== @@ -20754,23 +20394,6 @@ node-gyp-build@^4.2.1: resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.4.0.tgz#42e99687ce87ddeaf3a10b99dc06abc11021f3f4" integrity sha512-amJnQCcgtRVw9SvoebO3BKGESClrfXGCUTX9hSn1OuGQTQBOZmVd0Z0OlecpuRksKvbsUqALE8jls/ErClAPuQ== -node-gyp@^5.0.2, node-gyp@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-5.1.1.tgz#eb915f7b631c937d282e33aed44cb7a025f62a3e" - integrity sha512-WH0WKGi+a4i4DUt2mHnvocex/xPLp9pYt5R6M2JdFB7pJ7Z34hveZ4nDTGTiLXCkitA9T8HFZjhinBCiVHYcWw== - dependencies: - env-paths "^2.2.0" - glob "^7.1.4" - graceful-fs "^4.2.2" - mkdirp "^0.5.1" - nopt "^4.0.1" - npmlog "^4.1.2" - request "^2.88.0" - rimraf "^2.6.3" - semver "^5.7.1" - tar "^4.4.12" - which "^1.3.1" - node-gyp@^8.4.0: version "8.4.1" resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-8.4.1.tgz#3d49308fc31f768180957d6b5746845fbd429937" @@ -20831,23 +20454,33 @@ node-modules-regexp@^1.0.0: resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= -node-notifier@^10.0.0, node-notifier@^8.0.1: - version "8.0.2" - resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-8.0.2.tgz#f3167a38ef0d2c8a866a83e318c1ba0efeb702c5" - integrity sha512-oJP/9NAdd9+x2Q+rfphB2RJCHjod70RcRLjosiPMMu5gjIfwVnOUGq2nbTjTUbmy0DJ/tFIVT30+Qe3nzl4TJg== +node-notifier@^10.0.0: + version "10.0.1" + resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-10.0.1.tgz#0e82014a15a8456c4cfcdb25858750399ae5f1c7" + integrity sha512-YX7TSyDukOZ0g+gmzjB6abKu+hTGvO8+8+gIFDsRCU2t8fLV/P2unmt+LGFaIa4y64aX98Qksa97rgz4vMNeLQ== dependencies: growly "^1.3.0" is-wsl "^2.2.0" - semver "^7.3.2" + semver "^7.3.5" shellwords "^0.1.1" - uuid "^8.3.0" + uuid "^8.3.2" which "^2.0.2" +node-releases@^1.1.61: + version "1.1.77" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.77.tgz#50b0cfede855dd374e7585bf228ff34e57c1c32e" + integrity sha512-rB1DUFUNAN4Gn9keO2K1efO35IDK7yKHCdCaIMvFO7yUYmmZYeDjnGKle26G4rwj+LKRQpjyUUvMkPglwGCYNQ== + node-releases@^2.0.8: version "2.0.10" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.10.tgz#c311ebae3b6a148c89b1813fd7c4d3c024ef537f" integrity sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w== +node-uuid@~1.4.0: + version "1.4.8" + resolved "https://registry.yarnpkg.com/node-uuid/-/node-uuid-1.4.8.tgz#b040eb0923968afabf8d32fb1f17f1167fdab907" + integrity sha512-TkCET/3rr9mUuRp+CpO7qfgT++aAxfDRaalQhwPFzI9BY/2rCDn6OfpZOVggi1AXfTPpfkTrg5f5WQx5G1uLxA== + node-watch@0.7.3: version "0.7.3" resolved "https://registry.yarnpkg.com/node-watch/-/node-watch-0.7.3.tgz#6d4db88e39c8d09d3ea61d6568d80e5975abc7ab" @@ -20868,7 +20501,7 @@ nopt@^3.0.6: dependencies: abbrev "1" -nopt@^4.0.1, nopt@^4.0.3: +nopt@^4.0.1: version "4.0.3" resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.3.tgz#a375cad9d02fd921278d954c2254d5aa57e15e48" integrity sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg== @@ -20883,7 +20516,7 @@ nopt@^5.0.0: dependencies: abbrev "1" -normalize-package-data@^2.0.0, normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package-data@^2.4.0, normalize-package-data@^2.5.0: +normalize-package-data@^2.0.0, normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package-data@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== @@ -20920,30 +20553,15 @@ normalize-range@^0.1.2: resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI= -normalize-url@^4.5.1, normalize-url@^6.0.1: +normalize-url@^4.1.0: version "4.5.1" resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.1.tgz#0dd90cf1288ee1d1313b87081c9a5932ee48518a" integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA== -npm-audit-report@^1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/npm-audit-report/-/npm-audit-report-1.3.3.tgz#8226deeb253b55176ed147592a3995442f2179ed" - integrity sha512-8nH/JjsFfAWMvn474HB9mpmMjrnKb1Hx/oTAdjv4PT9iZBvBxiZ+wtDUapHCJwLqYGQVPaAfs+vL5+5k9QndXw== - dependencies: - cli-table3 "^0.5.0" - console-control-strings "^1.1.0" - -npm-bundled@^1.0.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.1.2.tgz#944c78789bd739035b70baa2ca5cc32b8d860bc1" - integrity sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ== - dependencies: - npm-normalize-package-bin "^1.0.1" - -npm-cache-filename@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/npm-cache-filename/-/npm-cache-filename-1.0.2.tgz#ded306c5b0bfc870a9e9faf823bc5f283e05ae11" - integrity sha512-5v2y1KG06izpGvZJDSBR5q1Ej+NaPDO05yAAWBJE6+3eiId0R176Gz3Qc2vEmJnE+VGul84g6Qpq8fXzD82/JA== +normalize-url@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" + integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== npm-conf@^1.1.3: version "1.1.3" @@ -20958,48 +20576,12 @@ npm-git-info@^1.0.3: resolved "https://registry.yarnpkg.com/npm-git-info/-/npm-git-info-1.0.3.tgz#a933c42ec321e80d3646e0d6e844afe94630e1d5" integrity sha512-i5WBdj4F/ULl16z9ZhsJDMl1EQCMQhHZzBwNnKL2LOA+T8IHNeRkLCVz9uVV9SzUdGTbDq+1oXhIYMe+8148vw== -npm-install-checks@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/npm-install-checks/-/npm-install-checks-3.0.2.tgz#ab2e32ad27baa46720706908e5b14c1852de44d9" - integrity sha512-E4kzkyZDIWoin6uT5howP8VDvkM+E8IQDcHAycaAxMbwkqhIg5eEYALnXOl3Hq9MrkdQB/2/g1xwBINXdKSRkg== - dependencies: - semver "^2.3.0 || 3.x || 4 || 5" - -npm-lifecycle@^3.0.0, npm-lifecycle@^3.1.5: - version "3.1.5" - resolved "https://registry.yarnpkg.com/npm-lifecycle/-/npm-lifecycle-3.1.5.tgz#9882d3642b8c82c815782a12e6a1bfeed0026309" - integrity sha512-lDLVkjfZmvmfvpvBzA4vzee9cn+Me4orq0QF8glbswJVEbIcSNWib7qGOffolysc3teCqbbPZZkzbr3GQZTL1g== - dependencies: - byline "^5.0.0" - graceful-fs "^4.1.15" - node-gyp "^5.0.2" - resolve-from "^4.0.0" - slide "^1.1.6" - uid-number "0.0.6" - umask "^1.1.0" - which "^1.3.1" - -npm-logical-tree@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/npm-logical-tree/-/npm-logical-tree-1.2.1.tgz#44610141ca24664cad35d1e607176193fd8f5b88" - integrity sha512-AJI/qxDB2PWI4LG1CYN579AY1vCiNyWfkiquCsJWqntRu/WwimVrC8yXeILBFHDwxfOejxewlmnvW9XXjMlYIg== - -npm-normalize-package-bin@^1.0.0, npm-normalize-package-bin@^1.0.1: +npm-normalize-package-bin@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2" integrity sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA== -"npm-package-arg@^4.0.0 || ^5.0.0 || ^6.0.0", npm-package-arg@^6.0.0, npm-package-arg@^6.1.0, npm-package-arg@^6.1.1: - version "6.1.1" - resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-6.1.1.tgz#02168cb0a49a2b75bf988a28698de7b529df5cb7" - integrity sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg== - dependencies: - hosted-git-info "^2.7.1" - osenv "^0.1.5" - semver "^5.6.0" - validate-npm-package-name "^3.0.0" - -npm-package-arg@^8.0.0, npm-package-arg@^8.1.5: +npm-package-arg@^8.1.5: version "8.1.5" resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-8.1.5.tgz#3369b2d5fe8fdc674baa7f1786514ddc15466e44" integrity sha512-LhgZrg0n0VgvzVdSm1oiZworPbTxYHUJCgtsJW8mGvlDpxTM1vSJc3m5QZeUkhAHIzbz3VCHd/R4osi1L1Tg/Q== @@ -21018,47 +20600,6 @@ npm-package-arg@^9.1.0: semver "^7.3.5" validate-npm-package-name "^4.0.0" -npm-packlist@^1.1.12, npm-packlist@^1.4.8: - version "1.4.8" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.8.tgz#56ee6cc135b9f98ad3d51c1c95da22bbb9b2ef3e" - integrity sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A== - dependencies: - ignore-walk "^3.0.1" - npm-bundled "^1.0.1" - npm-normalize-package-bin "^1.0.1" - -npm-pick-manifest@^3.0.0, npm-pick-manifest@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-3.0.2.tgz#f4d9e5fd4be2153e5f4e5f9b7be8dc419a99abb7" - integrity sha512-wNprTNg+X5nf+tDi+hbjdHhM4bX+mKqv6XmPh7B5eG+QY9VARfQPfCEH013H5GqfNj6ee8Ij2fg8yk0mzps1Vw== - dependencies: - figgy-pudding "^3.5.1" - npm-package-arg "^6.0.0" - semver "^5.4.1" - -npm-profile@^4.0.2, npm-profile@^4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/npm-profile/-/npm-profile-4.0.4.tgz#28ee94390e936df6d084263ee2061336a6a1581b" - integrity sha512-Ta8xq8TLMpqssF0H60BXS1A90iMoM6GeKwsmravJ6wYjWwSzcYBTdyWa3DZCYqPutacBMEm7cxiOkiIeCUAHDQ== - dependencies: - aproba "^1.1.2 || 2" - figgy-pudding "^3.4.1" - npm-registry-fetch "^4.0.0" - -npm-registry-fetch@^4.0.0, npm-registry-fetch@^4.0.7, npm-registry-fetch@~8.1.1: - version "8.1.5" - resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-8.1.5.tgz#33270c6722030c2d158a970d1327dcd9a149b5c5" - integrity sha512-yZPNoJK9clx1jhSXU54kU6Aj1SV2p7mXUs1W/6OjQvek3wb1RrjDCrt4iY1+VX9eBQvvSGEpzNmYkRUaTL8rqg== - dependencies: - "@npmcli/ci-detect" "^1.0.0" - lru-cache "^6.0.0" - make-fetch-happen "^8.0.9" - minipass "^3.1.3" - minipass-fetch "^1.3.0" - minipass-json-stream "^1.0.1" - minizlib "^2.0.0" - npm-package-arg "^8.0.0" - npm-run-all@^4.1.5: version "4.1.5" resolved "https://registry.yarnpkg.com/npm-run-all/-/npm-run-all-4.1.5.tgz#04476202a15ee0e2e214080861bff12a51d98fba" @@ -21102,133 +20643,7 @@ npm-run-path@^5.1.0: dependencies: path-key "^4.0.0" -npm-user-validate@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/npm-user-validate/-/npm-user-validate-1.0.1.tgz#31428fc5475fe8416023f178c0ab47935ad8c561" - integrity sha512-uQwcd/tY+h1jnEaze6cdX/LrhWhoBxfSknxentoqmIuStxUExxjWd3ULMLFPiFUrZKbOVMowH6Jq2FRWfmhcEw== - -npm@~6.14.6: - version "6.14.18" - resolved "https://registry.yarnpkg.com/npm/-/npm-6.14.18.tgz#5cd431567f0961e1fe63d46738cf37f74f7999eb" - integrity sha512-p3SjqSchSuNQUqbJBgwdv0L3O6bKkaSfQrQzJsskNpNKLg0g37c5xTXFV0SqTlX9GWvoGxBELVJMRWq0J8oaLA== - dependencies: - JSONStream "^1.3.5" - abbrev "~1.1.1" - ansicolors "~0.3.2" - ansistyles "~0.1.3" - aproba "^2.0.0" - archy "~1.0.0" - bin-links "^1.1.8" - bluebird "^3.7.2" - byte-size "^5.0.1" - cacache "^12.0.4" - call-limit "^1.1.1" - chownr "^1.1.4" - ci-info "^2.0.0" - cli-columns "^3.1.2" - cli-table3 "^0.5.1" - cmd-shim "^3.0.3" - columnify "~1.5.4" - config-chain "^1.1.13" - detect-indent "~5.0.0" - detect-newline "^2.1.0" - dezalgo "^1.0.4" - editor "~1.0.0" - figgy-pudding "^3.5.2" - find-npm-prefix "^1.0.2" - fs-vacuum "~1.2.10" - fs-write-stream-atomic "~1.0.10" - gentle-fs "^2.3.1" - glob "^7.2.3" - graceful-fs "^4.2.10" - has-unicode "~2.0.1" - hosted-git-info "^2.8.9" - iferr "^1.0.2" - infer-owner "^1.0.4" - inflight "~1.0.6" - inherits "^2.0.4" - ini "^1.3.8" - init-package-json "^1.10.3" - is-cidr "^3.1.1" - json-parse-better-errors "^1.0.2" - lazy-property "~1.0.0" - libcipm "^4.0.8" - libnpm "^3.0.1" - libnpmaccess "^3.0.2" - libnpmhook "^5.0.3" - libnpmorg "^1.0.1" - libnpmsearch "^2.0.2" - libnpmteam "^1.0.2" - libnpx "^10.2.4" - lock-verify "^2.2.2" - lockfile "^1.0.4" - lodash._baseuniq "~4.6.0" - lodash.clonedeep "~4.5.0" - lodash.union "~4.6.0" - lodash.uniq "~4.5.0" - lodash.without "~4.4.0" - lru-cache "^5.1.1" - meant "^1.0.3" - mississippi "^3.0.0" - mkdirp "^0.5.6" - move-concurrently "^1.0.1" - node-gyp "^5.1.1" - nopt "^4.0.3" - normalize-package-data "^2.5.0" - npm-audit-report "^1.3.3" - npm-cache-filename "~1.0.2" - npm-install-checks "^3.0.2" - npm-lifecycle "^3.1.5" - npm-package-arg "^6.1.1" - npm-packlist "^1.4.8" - npm-pick-manifest "^3.0.2" - npm-profile "^4.0.4" - npm-registry-fetch "^4.0.7" - npm-user-validate "^1.0.1" - npmlog "~4.1.2" - once "~1.4.0" - opener "^1.5.2" - osenv "^0.1.5" - pacote "^9.5.12" - path-is-inside "~1.0.2" - promise-inflight "~1.0.1" - qrcode-terminal "^0.12.0" - query-string "^6.14.1" - qw "^1.0.2" - read "~1.0.7" - read-cmd-shim "^1.0.5" - read-installed "~4.0.3" - read-package-json "^2.1.2" - read-package-tree "^5.3.1" - readable-stream "^3.6.0" - readdir-scoped-modules "^1.1.0" - request "^2.88.2" - retry "^0.12.0" - rimraf "^2.7.1" - safe-buffer "^5.2.1" - semver "^5.7.1" - sha "^3.0.0" - slide "~1.1.6" - sorted-object "~2.0.1" - sorted-union-stream "~2.1.3" - ssri "^6.0.2" - stringify-package "^1.0.1" - tar "^4.4.19" - text-table "~0.2.0" - tiny-relative-date "^1.3.0" - uid-number "0.0.6" - umask "~1.1.0" - unique-filename "^1.1.1" - unpipe "~1.0.0" - update-notifier "^2.5.0" - uuid "^3.4.0" - validate-npm-package-license "^3.0.4" - validate-npm-package-name "~3.0.0" - which "^1.3.1" - worker-farm "^1.7.0" - write-file-atomic "^2.4.3" - -npmlog@^4.1.2, npmlog@~4.1.2: +npmlog@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== @@ -21258,7 +20673,14 @@ npmlog@^6.0.0: gauge "^4.0.3" set-blocking "^2.0.0" -nth-check@^1.0.2, nth-check@^2.0.0, nth-check@^2.0.1: +nth-check@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" + integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg== + dependencies: + boolbase "~1.0.0" + +nth-check@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d" integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w== @@ -21293,6 +20715,11 @@ nwsapi@^2.2.0: resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== +oauth-sign@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.3.0.tgz#cb540f93bb2b22a7d5941691a288d60e8ea9386e" + integrity sha512-Tr31Sh5FnK9YKm7xTUPyDMsNOvMqkVDND0zvK/Wgj7/H9q8mpye0qG2nVzrnsvLhcsX5DtqXD0la0ks6rkPCGQ== + oauth-sign@~0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" @@ -21422,7 +20849,7 @@ on-headers@~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, once@~1.4.0: +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 sha1-WDsap3WWHUsROsF9nFC6753Xa9E= @@ -21467,11 +20894,6 @@ open@^8.1.0: is-docker "^2.1.1" is-wsl "^2.2.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== - optionator@^0.8.1: version "0.8.3" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" @@ -21538,7 +20960,7 @@ os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.1, os-tmpdir@~1.0.2: resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= -osenv@^0.1.3, osenv@^0.1.4, osenv@^0.1.5: +osenv@^0.1.3, osenv@^0.1.4: version "0.1.5" resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== @@ -21558,6 +20980,11 @@ p-all@^2.1.0: dependencies: p-map "^2.0.0" +p-cancelable@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" + integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== + p-cancelable@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.1.tgz#aab7fbd416582fa32a3db49859c122487c5ed2cf" @@ -21715,16 +21142,6 @@ p-try@^2.0.0: resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== -package-json@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" - integrity sha512-q/R5GrMek0vzgoomq6rm9OX+3PQve8sLwTirmK30YB3Cu0Bbt9OX9M/SIUnroN5BGJkzwGsFwDaRGD9EwBOlCA== - dependencies: - got "^6.7.1" - registry-auth-token "^3.0.1" - registry-url "^3.0.3" - semver "^5.1.0" - package-json@^6.3.0: version "6.5.0" resolved "https://registry.yarnpkg.com/package-json/-/package-json-6.5.0.tgz#6feedaca35e75725876d0b0e64974697fed145b0" @@ -21735,42 +21152,6 @@ package-json@^6.3.0: registry-url "^5.0.0" semver "^6.2.0" -pacote@^9.1.0, pacote@^9.5.12, pacote@^9.5.3: - version "9.5.12" - resolved "https://registry.yarnpkg.com/pacote/-/pacote-9.5.12.tgz#1e11dd7a8d736bcc36b375a9804d41bb0377bf66" - integrity sha512-BUIj/4kKbwWg4RtnBncXPJd15piFSVNpTzY0rysSr3VnMowTYgkGKcaHrbReepAkjTr8lH2CVWRi58Spg2CicQ== - dependencies: - bluebird "^3.5.3" - cacache "^12.0.2" - chownr "^1.1.2" - figgy-pudding "^3.5.1" - get-stream "^4.1.0" - glob "^7.1.3" - infer-owner "^1.0.4" - lru-cache "^5.1.1" - make-fetch-happen "^5.0.0" - minimatch "^3.0.4" - minipass "^2.3.5" - mississippi "^3.0.0" - mkdirp "^0.5.1" - normalize-package-data "^2.4.0" - npm-normalize-package-bin "^1.0.0" - npm-package-arg "^6.1.0" - npm-packlist "^1.1.12" - npm-pick-manifest "^3.0.0" - npm-registry-fetch "^4.0.0" - osenv "^0.1.5" - promise-inflight "^1.0.1" - promise-retry "^1.1.1" - protoduck "^5.0.1" - rimraf "^2.6.2" - safe-buffer "^5.1.2" - semver "^5.6.0" - ssri "^6.0.1" - tar "^4.4.10" - unique-filename "^1.1.1" - which "^1.3.1" - pako@~1.0.5: version "1.0.11" resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" @@ -21910,6 +21291,11 @@ 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@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" @@ -21937,11 +21323,6 @@ path-is-absolute@1.0.1, path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= -path-is-inside@^1.0.1, path-is-inside@^1.0.2, path-is-inside@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" - integrity sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w== - path-key@^2.0.0, path-key@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" @@ -22164,7 +21545,7 @@ playwright@^1.15.0: ws "^7.4.6" yazl "^2.5.1" -plist@^3.0.0, plist@^3.0.1, plist@^3.0.4, plist@^3.0.5: +plist@^3.0.0, plist@^3.0.1, plist@^3.0.4: version "3.0.6" resolved "https://registry.yarnpkg.com/plist/-/plist-3.0.6.tgz#7cfb68a856a7834bca6dbfe3218eb9c7740145d3" integrity sha512-WiIVYyrp8TD4w8yCvyeIr+lkmrGRd5u0VbRnU+tP/aRLxP/YadJUYOMZJ/6hIa3oUyVCsycXvtNRgd5XBJIbiA== @@ -22376,6 +21757,11 @@ prelude-ls@~1.1.2: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= +prepend-http@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" + integrity sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA== + pretender@^3.4.3, pretender@^3.4.7: version "3.4.7" resolved "https://registry.yarnpkg.com/pretender/-/pretender-3.4.7.tgz#34a2ae2d1fc9db440a990d50e6c0f5481d8755fc" @@ -22450,11 +21836,21 @@ printf@^0.6.1: resolved "https://registry.yarnpkg.com/printf/-/printf-0.6.1.tgz#b9afa3d3b55b7f2e8b1715272479fc756ed88650" integrity sha512-is0ctgGdPJ5951KulgfzvHGwJtZ5ck8l042vRkV6jrkpBzTmb/lueTqguWHy2JfVA+RY6gFVlaZgUS0j7S/dsw== -prismjs@^1.21.0, prismjs@^1.27.0, prismjs@~1.24.0, prismjs@~1.27.0: +prismjs@^1.21.0, prismjs@^1.27.0: version "1.29.0" resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.29.0.tgz#f113555a8fa9b57c35e637bba27509dcf802dd12" integrity sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q== +prismjs@~1.24.0: + version "1.24.1" + resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.24.1.tgz#c4d7895c4d6500289482fa8936d9cdd192684036" + integrity sha512-mNPsedLuk90RVJioIky8ANZEwYm5w9LcvCXrxHlwf4fNVSn8jEipMybMkWUyyF0JhnC+C4VcOVSBuHRKs1L5Ow== + +prismjs@~1.27.0: + version "1.27.0" + resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.27.0.tgz#bb6ee3138a0b438a3653dd4d6ce0cc6510a45057" + integrity sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA== + private@^0.1.8: version "0.1.8" resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" @@ -22495,7 +21891,7 @@ progress@^2.0.0, progress@^2.0.1, progress@^2.0.3: resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== -promise-inflight@^1.0.1, promise-inflight@~1.0.1: +promise-inflight@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= @@ -22512,14 +21908,6 @@ promise-map-series@^0.3.0: resolved "https://registry.yarnpkg.com/promise-map-series/-/promise-map-series-0.3.0.tgz#41873ca3652bb7a042b387d538552da9b576f8a1" integrity sha512-3npG2NGhTc8BWBolLLf8l/92OxMGaRLbqvIh9wjCHhDXNvk4zsxaTaCpiCunW09qWPrN2zeNSNwRLVBrQQtutA== -promise-retry@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-1.1.1.tgz#6739e968e3051da20ce6497fb2b50f6911df3d6d" - integrity sha512-StEy2osPr28o17bIW776GtwO6+Q+M9zPiZkYfosciUUMYqjhU/ffwRAH0zN2+uvGyUsn8/YICIHRzLbPacpZGw== - dependencies: - err-code "^1.0.0" - retry "^0.10.0" - promise-retry@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-2.0.1.tgz#ff747a13620ab57ba688f5fc67855410c370da22" @@ -22578,13 +21966,6 @@ prompts@^2.4.0: kleur "^3.0.3" sisteransi "^1.0.5" -promzard@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/promzard/-/promzard-0.3.0.tgz#26a5d6ee8c7dee4cb12208305acfb93ba382a9ee" - integrity sha512-JZeYqd7UAcHCwI+sTOeUDYkvEU+1bQ7iE0UT1MgB/tERkAPkesW46MrpIySzODi+owTjZtiF8Ay5j9m60KmMBw== - dependencies: - read "1" - prop-types@^15.0.0, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: version "15.7.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" @@ -22615,13 +21996,6 @@ proto-list@~1.2.1: resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk= -protoduck@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/protoduck/-/protoduck-5.0.1.tgz#03c3659ca18007b69a50fd82a7ebcc516261151f" - integrity sha512-WxoCeDCoCBY55BMvj4cAEjdVUFGRWed9ZxPlqTKYyw1nDDTQ4pqmnIMAGfJlg7Dx35uB/M+PHJPTmGOvaCaPTg== - dependencies: - genfun "^5.0.0" - proxy-addr@~2.0.7: version "2.0.7" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" @@ -22640,10 +22014,10 @@ prr@~1.0.1: resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= -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.28, 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" @@ -22687,7 +22061,7 @@ punycode@1.3.2: resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= -punycode@^1.2.4, punycode@^1.4.1: +punycode@^1.2.4: version "1.4.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" integrity sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ== @@ -22725,11 +22099,6 @@ q@^1.1.2: resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= -qrcode-terminal@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/qrcode-terminal/-/qrcode-terminal-0.12.0.tgz#bb5b699ef7f9f0505092a3748be4464fe71b5819" - integrity sha512-EXtzRZmC+YGmGlDFbXKxQiMZNwCLEO6BANKXG4iCtSIM0yqc/pappSx3RIKr4r0uh5JsBckOXeKrB3Iz7mdQpQ== - qs@6.11.0, qs@^6.10.0, qs@^6.4.0: version "6.11.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" @@ -22737,21 +22106,16 @@ qs@6.11.0, qs@^6.10.0, qs@^6.4.0: dependencies: side-channel "^1.0.4" +qs@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-1.0.2.tgz#50a93e2b5af6691c31bcea5dae78ee6ea1903768" + integrity sha512-tHuOP9TN/1VmDM/ylApGK1QF3PSIP8I6bHDEfoKNQeViREQ/sfu1bAUrA1hoDun8p8Tpm7jcsz47g+3PiGoYdg== + qs@~6.5.2: version "6.5.3" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad" integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA== -query-string@^6.14.1: - version "6.14.1" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.14.1.tgz#7ac2dca46da7f309449ba0f86b1fd28255b0c86a" - integrity sha512-XDxAeVmpfu1/6IjyT/gXHOl+S0vQ9owggJ30hhWKdHAsNPOcasn5o9BW0eejZqL2e4vMjhAxoW3jVHcD6mbcYw== - dependencies: - decode-uri-component "^0.2.0" - filter-obj "^1.1.0" - split-on-first "^1.0.0" - strict-uri-encode "^2.0.0" - querystring-es3@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" @@ -22767,6 +22131,11 @@ querystring@^0.2.0: 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== + queue-microtask@^1.2.2: version "1.2.3" resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" @@ -22810,11 +22179,6 @@ qunit@^2.17.2, qunit@^2.19.1: node-watch "0.7.3" tiny-glob "0.2.9" -qw@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/qw/-/qw-1.0.2.tgz#0c31a6f810320a91c58b05198679427103b03c4a" - integrity sha512-1PhZ/iLKwlVNq45dnerTMKFjMof49uqli7/0QsvPNbX5OJ3IZ8msa9lUpvPheVdP+IYYPrf6cOaVil7S35joVA== - ramda@^0.21.0: version "0.21.0" resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.21.0.tgz#a001abedb3ff61077d4ff1d577d44de77e8d0a35" @@ -22866,7 +22230,7 @@ raw-loader@^4.0.2: loader-utils "^2.0.0" schema-utils "^3.0.0" -rc@^1.0.1, rc@^1.1.6, rc@^1.2.8: +rc@^1.2.8: version "1.2.8" resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== @@ -23057,13 +22421,6 @@ react@16.14.0, react@^16: object-assign "^4.1.1" prop-types "^15.6.2" -read-cmd-shim@^1.0.1, read-cmd-shim@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/read-cmd-shim/-/read-cmd-shim-1.0.5.tgz#87e43eba50098ba5a32d0ceb583ab8e43b961c16" - integrity sha512-v5yCqQ/7okKoZZkBQUAfTsQ3sVJtXdNfbPnI5cceppoxEVLYA3k+VtV2omkeo8MS94JCy4fSiUwlRBAwCVRPUA== - dependencies: - graceful-fs "^4.1.2" - read-installed@~4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/read-installed/-/read-installed-4.0.3.tgz#ff9b8b67f187d1e4c29b9feb31f6b223acd19067" @@ -23078,7 +22435,7 @@ read-installed@~4.0.3: optionalDependencies: graceful-fs "^4.1.2" -"read-package-json@1 || 2", read-package-json@^2.0.0, read-package-json@^2.0.13, read-package-json@^2.1.2: +read-package-json@^2.0.0: version "2.1.2" resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-2.1.2.tgz#6992b2b66c7177259feb8eaac73c3acd28b9222a" integrity sha512-D1KmuLQr6ZSJS0tW8hf3WGpRlwszJOXZ3E8Yd/DNRaM5d+1wVRZdHlpGBLAuovjr28LbWvjpWkBHMxpRGGjzNA== @@ -23159,13 +22516,6 @@ read-pkg@^5.2.0: parse-json "^5.0.0" type-fest "^0.6.0" -read@1, read@~1.0.1, read@~1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4" - integrity sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ== - dependencies: - mute-stream "~0.0.4" - "readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, 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.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" @@ -23188,18 +22538,14 @@ read@1, read@~1.0.1, read@~1.0.7: string_decoder "^1.1.1" util-deprecate "^1.0.1" -readable-stream@^2.3.5: - version "2.3.8" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" - integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== +readable-stream@^3.4.0: + version "3.6.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== 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" + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" readable-stream@~1.0.2: version "1.0.34" @@ -23211,7 +22557,7 @@ readable-stream@~1.0.2: isarray "0.0.1" string_decoder "~0.10.x" -readable-stream@~1.1.10, readable-stream@~1.1.9: +readable-stream@~1.1.9: version "1.1.14" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" integrity sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ== @@ -23221,7 +22567,7 @@ readable-stream@~1.1.10, readable-stream@~1.1.9: isarray "0.0.1" string_decoder "~0.10.x" -readdir-scoped-modules@^1.0.0, readdir-scoped-modules@^1.1.0: +readdir-scoped-modules@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz#8d45407b4f870a0dcaebc0e28670d18e74514309" integrity sha512-asaikDeqAQg7JifRsZn1NJZXo9E+VwlyCfbkZhwyISinqk5zNS6266HS5kah6P0SaQKGF6SkNnZVHUzHFYxYDw== @@ -23434,14 +22780,6 @@ regexpu-core@^5.1.0: unicode-match-property-ecmascript "^2.0.0" unicode-match-property-value-ecmascript "^2.0.0" -registry-auth-token@^3.0.1: - version "3.4.0" - resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.4.0.tgz#d7446815433f5d5ed6431cd5dca21048f66b397e" - integrity sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A== - dependencies: - rc "^1.1.6" - safe-buffer "^5.0.1" - registry-auth-token@^4.0.0: version "4.2.1" resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-4.2.1.tgz#6d7b4006441918972ccd5fedcd41dc322c79b250" @@ -23449,13 +22787,6 @@ registry-auth-token@^4.0.0: dependencies: rc "^1.2.8" -registry-url@^3.0.3: - version "3.1.0" - resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942" - integrity sha512-ZbgR5aZEdf4UKZVBPYIgaglBmSF2Hi94s2PcIHhRGFjKYu+chjJdYfHn4rt3hB6eCKLJ8giVIIfgMa1ehDfZKA== - dependencies: - rc "^1.0.1" - registry-url@^5.0.0: version "5.1.0" resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-5.1.0.tgz#e98334b50d5434b81136b44ec638d9c2009c5009" @@ -23634,7 +22965,7 @@ repeating@^2.0.0: dependencies: is-finite "^1.0.0" -request@^2.45.0, request@^2.88.0, request@^2.88.2, request@~2.40.0: +request@^2.45.0: version "2.88.2" resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== @@ -23660,6 +22991,26 @@ request@^2.45.0, request@^2.88.0, request@^2.88.2, request@~2.40.0: tunnel-agent "^0.6.0" uuid "^3.3.2" +request@~2.40.0: + version "2.40.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.40.0.tgz#4dd670f696f1e6e842e66b4b5e839301ab9beb67" + integrity sha512-waNoGB4Z7bPn+lgqPk7l7hhze4Vd68jKccnwLeS7vr9GMxz0iWQbYTbBNWzfIk87Urx7V44pu29qjF/omej+Fw== + dependencies: + forever-agent "~0.5.0" + json-stringify-safe "~5.0.0" + mime-types "~1.0.1" + node-uuid "~1.4.0" + qs "~1.0.0" + optionalDependencies: + aws-sign2 "~0.5.0" + form-data "~0.1.0" + hawk "1.1.1" + http-signature "~0.10.0" + oauth-sign "~0.3.0" + stringstream "~0.0.4" + tough-cookie ">=0.12.0" + tunnel-agent "~0.4.0" + require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" @@ -23670,11 +23021,6 @@ require-from-string@^2.0.2: resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== -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== - require-relative@^0.8.7: version "0.8.7" resolved "https://registry.yarnpkg.com/require-relative/-/require-relative-0.8.7.tgz#7999539fc9e047a37928fa196f8e1563dabd36de" @@ -23817,6 +23163,13 @@ resolve@^1.22.0, resolve@^1.22.1: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" +responselike@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" + integrity sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ== + dependencies: + lowercase-keys "^1.0.0" + responselike@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.0.tgz#26391bcc3174f750f9a79eacc40a12a5c42d7723" @@ -23845,11 +23198,6 @@ ret@~0.1.10: resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== -retry@^0.10.0: - version "0.10.1" - resolved "https://registry.yarnpkg.com/retry/-/retry-0.10.1.tgz#e76388d217992c252750241d3d3956fed98d8ff4" - integrity sha512-ZXUSQYTHdl3uS7IuCehYfMzKyIDBNoAuUblvy5oGO5UJSUTmStUUVPXbA9Qxd173Bgre53yCQczQuHgRWAdvJQ== - retry@^0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" @@ -23865,7 +23213,7 @@ rfdc@^1.3.0: resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== -rimraf@^2.2.8, rimraf@^2.3.4, rimraf@^2.4.1, rimraf@^2.4.3, rimraf@^2.5.2, rimraf@^2.5.3, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@^2.6.3, rimraf@^2.7.1: +rimraf@^2.2.8, rimraf@^2.3.4, rimraf@^2.4.1, rimraf@^2.4.3, rimraf@^2.5.3, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@^2.6.3: version "2.7.1" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== @@ -24000,7 +23348,7 @@ safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: 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.1.0, 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: +safe-buffer@5.2.1, safe-buffer@>=5.1.0, 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.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== @@ -24156,13 +23504,6 @@ semver-compare@^1.0.0: resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w= -semver-diff@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" - integrity sha512-gL8F8L4ORwsS0+iQ34yCYv///jsOq0ZL7WP55d1HnJ32o7tyFYEFQZQA22mrLIacZdU6xecaBBZ+uEiffGNyXw== - dependencies: - semver "^5.0.3" - semver-diff@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-3.1.1.tgz#05f77ce59f325e00e2706afd67bb506ddb1ca32b" @@ -24170,7 +23511,7 @@ semver-diff@^3.1.1: dependencies: semver "^6.3.0" -"semver@2 || 3 || 4 || 5", "semver@2.x || 3.x || 4 || 5", "semver@^2.3.0 || 3.x || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0, semver@^5.7.1: +"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.6.0: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== @@ -24272,13 +23613,15 @@ set-blocking@^2.0.0, set-blocking@~2.0.0: resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= -set-value@^2.0.0, set-value@^2.0.1, set-value@^4.0.1: - version "4.1.0" - resolved "https://registry.yarnpkg.com/set-value/-/set-value-4.1.0.tgz#aa433662d87081b75ad88a4743bd450f044e7d09" - integrity sha512-zTEg4HL0RwVrqcWs3ztF+x1vkxfm0lP+MQQFPiMJTKVceBwEV0A569Ou8l9IYQG8jOZdMVI1hGsc0tmeD2o/Lw== +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: - is-plain-object "^2.0.4" - is-primitive "^3.0.1" + 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" @@ -24303,13 +23646,6 @@ sha.js@^2.4.0, sha.js@^2.4.8: inherits "^2.0.1" safe-buffer "^5.0.1" -sha@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/sha/-/sha-3.0.0.tgz#b2f2f90af690c16a3a839a6a6c680ea51fedd1ae" - integrity sha512-DOYnM37cNsLNSGIG/zZWch5CKIRNoLdYUQTQlcgkRkoYIUwDYjqDyye16YcDZg/OPdcbUgTKMjc4SY6TB7ZAPw== - dependencies: - graceful-fs "^4.1.2" - shallow-clone@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" @@ -24346,12 +23682,17 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -shell-quote@1.7.2, shell-quote@^1.6.1, shell-quote@^1.7.3: +shell-quote@1.7.2: + version "1.7.2" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.2.tgz#67a7d02c76c9da24f99d20808fcaded0e0e04be2" + integrity sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg== + +shell-quote@^1.6.1: version "1.8.0" resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.0.tgz#20d078d0eaf71d54f43bd2ba14a1b5b9bfa5c8ba" integrity sha512-QHsz8GgQIGKlRi24yFc6a6lN69Idnx634w49ay6+jA5yFh7a1UY+4Rp6HPx/L/1zcEDPEij8cIsiqR6bQsE5VQ== -shelljs@^0.8.4, shelljs@^0.8.5: +shelljs@^0.8.4: version "0.8.5" resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.5.tgz#de055408d8361bed66c669d2f000538ced8ee20c" integrity sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow== @@ -24466,12 +23807,12 @@ slice-ansi@^5.0.0: ansi-styles "^6.0.0" is-fullwidth-code-point "^4.0.0" -slide@^1.1.6, slide@~1.1.3, slide@~1.1.6: +slide@~1.1.3: version "1.1.6" resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" integrity sha1-VusCfWW00tzmyy4tMsTUr8nh1wc= -smart-buffer@^4.1.0, smart-buffer@^4.2.0: +smart-buffer@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== @@ -24514,6 +23855,13 @@ snapdragon@^0.8.1: source-map-resolve "^0.5.0" use "^3.1.0" +sntp@0.2.x: + version "0.2.4" + resolved "https://registry.yarnpkg.com/sntp/-/sntp-0.2.4.tgz#fb885f18b0f3aad189f824862536bceeec750900" + integrity sha512-bDLrKa/ywz65gCl+LmOiIhteP1bhEsAAzhfMedPoiHP3dyYnAevlaJshdqb9Yu0sRifyP/fRqSt8t+5qGIWlGQ== + dependencies: + hoek "0.9.x" + socket.io-adapter@~2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.4.0.tgz#b50a4a9ecdd00c34d4c8c808224daa1a786152a6" @@ -24539,23 +23887,6 @@ socket.io@^4.1.2: socket.io-adapter "~2.4.0" socket.io-parser "~4.2.1" -socks-proxy-agent@^4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-4.0.2.tgz#3c8991f3145b2799e70e11bd5fbc8b1963116386" - integrity sha512-NT6syHhI9LmuEMSK6Kd2V7gNv5KFZoLE7V5udWmn0de+3Mkj3UMA/AJPLyeNUVmElCurSHtUdM3ETpR3z770Wg== - dependencies: - agent-base "~4.2.1" - socks "~2.3.2" - -socks-proxy-agent@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-5.0.1.tgz#032fb583048a29ebffec2e6a73fca0761f48177e" - integrity sha512-vZdmnjb9a2Tz6WEQVIurybSwElwPxMZaIc7PzqbJTrezcKNznv6giT7J7tZDZ1BojVaa1jvO/UiUdhDVB0ACoQ== - dependencies: - agent-base "^6.0.2" - debug "4" - socks "^2.3.3" - socks-proxy-agent@^6.0.0: version "6.2.1" resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-6.2.1.tgz#2687a31f9d7185e38d530bef1944fe1f1496d6ce" @@ -24565,14 +23896,6 @@ socks-proxy-agent@^6.0.0: debug "^4.3.3" socks "^2.6.2" -socks@^2.3.3: - version "2.7.1" - resolved "https://registry.yarnpkg.com/socks/-/socks-2.7.1.tgz#d8e651247178fde79c0663043e07240196857d55" - integrity sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ== - dependencies: - ip "^2.0.0" - smart-buffer "^4.2.0" - socks@^2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/socks/-/socks-2.6.2.tgz#ec042d7960073d40d94268ff3bb727dc685f111a" @@ -24581,14 +23904,6 @@ socks@^2.6.2: ip "^1.1.5" smart-buffer "^4.2.0" -socks@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/socks/-/socks-2.3.3.tgz#01129f0a5d534d2b897712ed8aceab7ee65d78e3" - integrity sha512-o5t52PCNtVdiOvzMry7wU4aOqYWL0PeCXRWBEiJow4/i/wr+wpsJQ9awEu1EonLIqsfGd5qSgDdxEOvCdmBEpA== - dependencies: - ip "1.1.5" - smart-buffer "^4.1.0" - solid-js@^1.3.0: version "1.6.11" resolved "https://registry.yarnpkg.com/solid-js/-/solid-js-1.6.11.tgz#263a512bf94efd89245a77f58dc18c195302237f" @@ -24613,19 +23928,6 @@ sort-package-json@^1.55.0, sort-package-json@^1.57.0: is-plain-obj "2.1.0" sort-object-keys "^1.1.3" -sorted-object@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/sorted-object/-/sorted-object-2.0.1.tgz#7d631f4bd3a798a24af1dffcfbfe83337a5df5fc" - integrity sha512-oKAAs26HeTu3qbawzUGCkTOBv/5MRrcuJyRWwbfEnWdpXnXsj+WEM3HTvarV73tMcf9uBEZNZoNDVRL62VLxzA== - -sorted-union-stream@~2.1.3: - version "2.1.3" - resolved "https://registry.yarnpkg.com/sorted-union-stream/-/sorted-union-stream-2.1.3.tgz#c7794c7e077880052ff71a8d4a2dbb4a9a638ac7" - integrity sha512-RaKskQJZkmVREIwyAFho1RRU+sKjDdg51Crvxg2VxmIyiIrNhPNoJD/by5/pklWBXAZoO6LfAAGv8xd47p9TnQ== - dependencies: - from2 "^1.3.0" - stream-iterate "^1.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" @@ -24662,7 +23964,7 @@ source-map-support@^0.5.13, source-map-support@^0.5.16: buffer-from "^1.0.0" source-map "^0.6.0" -source-map-support@^0.5.6, source-map-support@~0.5.20: +source-map-support@^0.5.6, source-map-support@~0.5.12, source-map-support@~0.5.20: 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== @@ -24680,7 +23982,7 @@ source-map-url@^0.4.0: resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56" integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== -source-map@^0.4.2: +source-map@0.4.x, source-map@^0.4.2: version "0.4.4" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" integrity sha1-66T12pwNyZneaAMti092FzZSA2s= @@ -24788,12 +24090,7 @@ speedometer@~0.1.2: resolved "https://registry.yarnpkg.com/speedometer/-/speedometer-0.1.4.tgz#9876dbd2a169d3115402d48e6ea6329c8816a50d" integrity sha1-mHbb0qFp0xFUAtSObqYynIgWpQ0= -split-on-first@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/split-on-first/-/split-on-first-1.1.0.tgz#f610afeee3b12bce1d0c30425e76398b78249a5f" - integrity sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw== - -split-string@^3.0.2: +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== @@ -24830,7 +24127,7 @@ sshpk@^1.7.0: safer-buffer "^2.0.2" tweetnacl "~0.14.0" -ssri@^6.0.0, ssri@^6.0.1, ssri@^6.0.2: +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== @@ -24923,24 +24220,11 @@ stream-http@^2.7.2: to-arraybuffer "^1.0.0" xtend "^4.0.0" -stream-iterate@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/stream-iterate/-/stream-iterate-1.2.0.tgz#2bd7c77296c1702a46488b8ad41f79865eecd4e1" - integrity sha512-QVfGkdBQ8NzsSIiL3rV6AoFFWwMvlg1qpTwVQaMGY5XYThDUuNM4hYSzi8pbKlimTsWyQdaWRZE+jwlPsMiiZw== - dependencies: - readable-stream "^2.1.5" - stream-shift "^1.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== -strict-uri-encode@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546" - integrity sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ== - string-argv@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da" @@ -24968,7 +24252,7 @@ string-width@^1.0.1: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" -"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: +"string-width@^1.0.2 || 2", string-width@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== @@ -24985,7 +24269,7 @@ string-width@^1.0.1: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -string-width@^3.0.0, string-width@^3.1.0: +string-width@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== @@ -25107,10 +24391,10 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -stringify-package@^1.0.0, stringify-package@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/stringify-package/-/stringify-package-1.0.1.tgz#e5aa3643e7f74d0f28628b72f3dad5cecfc3ba85" - integrity sha512-sa4DUQsYciMP1xhKWGuFM04fB0LG/9DlluZoSVywUMRNvzid6XucHK0/90xGxRoHrAaROrcHK1aPKaijCtSrhg== +stringstream@~0.0.4: + version "0.0.6" + resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.6.tgz#7880225b0d4ad10e30927d167a1d6f2fd3b33a72" + integrity sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA== strip-ansi@6.0.0, strip-ansi@^6.0.0: version "6.0.0" @@ -25133,7 +24417,7 @@ strip-ansi@^4.0.0: dependencies: ansi-regex "^3.0.0" -strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: +strip-ansi@^5.1.0, strip-ansi@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== @@ -25588,7 +24872,7 @@ tapable@^2.1.1, tapable@^2.2.0: resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== -tar@^4.4.10, tar@^4.4.12, tar@^4.4.19, tar@^6.0.2, tar@^6.0.5, tar@^6.1.0, tar@^6.1.2, tar@^6.1.9: +tar@^6.0.2, tar@^6.0.5, tar@^6.1.0, tar@^6.1.2: version "6.1.13" resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.13.tgz#46e22529000f612180601a6fe0680e7da508847b" integrity sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw== @@ -25648,13 +24932,6 @@ temp@^0.8.1: dependencies: rimraf "~2.6.2" -term-size@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69" - integrity sha512-7dPUZQGy/+m3/wjVz3ZW5dobSoD/02NxJpoXUX0WIyjfVS3l0c+b/+9phIDFA7FHzkYtwtMFgeGZ/Y8jVTeqQQ== - dependencies: - execa "^0.7.0" - term-size@^2.1.0: version "2.2.1" resolved "https://registry.yarnpkg.com/term-size/-/term-size-2.2.1.tgz#2a6a54840432c2fb6320fea0f415531e90189f54" @@ -25710,7 +24987,16 @@ terser-webpack-plugin@^5.1.3: source-map "^0.6.1" terser "^5.7.2" -terser@^4.1.2, terser@^4.6.3, terser@^5.14.2, terser@^5.3.0, terser@^5.3.4, terser@^5.7.2: +terser@^4.1.2, terser@^4.6.3: + 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" + +terser@^5.3.0, terser@^5.3.4, terser@^5.7.2: version "5.16.6" resolved "https://registry.yarnpkg.com/terser/-/terser-5.16.6.tgz#f6c7a14a378ee0630fbe3ac8d1f41b4681109533" integrity sha512-IBZ+ZQIA9sMaXmRZCUMDjNH0D5AQQfdn4WUjHL0+1lF4TP1IHRJbrhb6fNaXWikrYQTSkb7SLxkeXAiy1p7mbg== @@ -25799,7 +25085,7 @@ testem@^3.8.0: tap-parser "^7.0.0" tmp "0.0.33" -text-table@0.2.0, text-table@^0.2.0, text-table@~0.2.0: +text-table@0.2.0, text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== @@ -25848,7 +25134,7 @@ through2@~0.2.3: readable-stream "~1.1.9" xtend "~2.1.1" -"through@>=2.2.7 <3", through@^2.3.6, through@^2.3.8: +through@^2.3.6, 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== @@ -25890,11 +25176,6 @@ tiny-lr@^2.0.0: object-assign "^4.1.0" qs "^6.4.0" -tiny-relative-date@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/tiny-relative-date/-/tiny-relative-date-1.3.0.tgz#fa08aad501ed730f31cc043181d995c39a935e07" - integrity sha512-MOQHpzllWxDCHHaDno30hhLfbouoYlOI8YlMNtvKe1zXbjEVhbcEovQxvZrPvtiYW630GQDoMMarCnjfyfHA+A== - tmp@0.0.28: version "0.0.28" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.28.tgz#172735b7f614ea7af39664fa84cf0de4e515d120" @@ -25923,7 +25204,7 @@ tmp@^0.2.1: dependencies: rimraf "^3.0.0" -tmpl@1.0.x, tmpl@^1.0.5: +tmpl@1.0.x: version "1.0.5" resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== @@ -25950,6 +25231,11 @@ to-object-path@^0.3.0: dependencies: kind-of "^3.0.2" +to-readable-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771" + integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q== + 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" @@ -25985,12 +25271,23 @@ toidentifier@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.0.0, tough-cookie@~2.3.3, tough-cookie@~2.5.0: - version "2.3.4" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.4.tgz#ec60cee38ac675063ffc97a5c18970578ee83655" - integrity sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA== +tough-cookie@>=0.12.0, tough-cookie@^4.0.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.2.tgz#e53e84b85f24e0b65dd526f46628db6c85f6b874" + integrity sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ== dependencies: - punycode "^1.4.1" + psl "^1.1.33" + punycode "^2.1.1" + universalify "^0.2.0" + url-parse "^1.5.3" + +tough-cookie@~2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== + dependencies: + psl "^1.1.28" + punycode "^2.1.1" tr46@^2.1.0: version "2.1.0" @@ -26041,7 +25338,12 @@ treeify@^1.1.0: resolved "https://registry.yarnpkg.com/treeify/-/treeify-1.1.0.tgz#4e31c6a463accd0943879f30667c4fdaff411bb8" integrity sha512-1m4RA7xVAJrSGrrXGs0L3YTwyvBs2S8PbRHaLZAkFw7JR8oIFwYtysxlBZhYIa7xSyiYJKZ3iGrrk55cGA3i9A== -trim-newlines@^1.0.0, trim-newlines@^3.0.0, trim-newlines@^3.0.1: +trim-newlines@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" + integrity sha512-Nm4cF79FhSTzrLKGDMi3I4utBtFv8qKy4sq1enftf2gMdpqI8oVQTAfySkTz5r49giVzDj88SVZXP4CeYQwjaw== + +trim-newlines@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-3.0.1.tgz#260a5d962d8b752425b32f3a7db0dcacd176c144" integrity sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw== @@ -26063,10 +25365,10 @@ trim-trailing-lines@^1.0.0: resolved "https://registry.yarnpkg.com/trim-trailing-lines/-/trim-trailing-lines-1.1.4.tgz#bd4abbec7cc880462f10b2c8b5ce1d8d1ec7c2c0" integrity sha512-rjUWSqnfTNrjbB9NQWfPMH/xRK1deHeGsHoVfpxJ++XeYXE0d6B1En37AHfw3jtfTU7dzMzZL2jjpe8Qb5gLIQ== -trim@0.0.1, trim@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/trim/-/trim-1.0.1.tgz#68e78f6178ccab9687a610752f4f5e5a7022ee8c" - integrity sha512-3JVP2YVqITUisXblCDq/Bi4P9457G/sdEamInkyvCsjbTcXLXIiG7XCb4kGMFWh6JGXesS3TKxOPtrncN/xe8w== +trim@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/trim/-/trim-0.0.1.tgz#5858547f6b290757ee95cccc666fb50084c460dd" + integrity sha512-YzQV+TZg4AxpKxaTHK3c3D+kRDCGVEE7LemdlQZoQXn0iennk10RsIoY6ikzAqJTc9Xjl9C1/waHom/J86ziAQ== trough@^1.0.0: version "1.0.5" @@ -26120,13 +25422,18 @@ tty-browserify@0.0.0: resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY= -tunnel-agent@^0.6.0, tunnel-agent@~0.6.0: +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" +tunnel-agent@~0.4.0: + version "0.4.3" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.4.3.tgz#6373db76909fe570e08d73583365ed828a74eeeb" + integrity sha512-e0IoVDWx8SDHc/hwFTqJDQ7CCDTEeGhmcT9jkWJjoGQSpgBz20nAMr80E3Tpk7PatJ1b37DQDgJR3CNSzcMOZQ== + tunnel@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c" @@ -26236,7 +25543,7 @@ typescript@~4.2.4: resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.4.tgz#8610b59747de028fda898a8aef0e103f156d0961" integrity sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg== -uc.micro@^1.0.1, uc.micro@^1.0.5: +uc.micro@^1.0.0, uc.micro@^1.0.1, uc.micro@^1.0.5: version "1.0.6" resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac" integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA== @@ -26246,16 +25553,6 @@ uglify-js@^3.1.4: resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.14.1.tgz#e2cb9fe34db9cb4cf7e35d1d26dfea28e09a7d06" integrity sha512-JhS3hmcVaXlp/xSo3PKY5R0JqKs5M3IV+exdLHW99qKvKivPO4Z8qbej6mte17SOPqAOVMjt/XGgWacnFSzM3g== -uid-number@0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" - integrity sha512-c461FXIljswCuscZn67xq9PpszkPT6RjheWFQTgCyabJrTUozElanb0YEqv2UGgk247YpcJkFBuSGNvBlpXM9w== - -umask@^1.1.0, umask@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/umask/-/umask-1.1.0.tgz#f29cebf01df517912bb58ff9c4e50fde8e33320d" - integrity sha512-lE/rxOhmiScJu9L6RTNVgB/zZbF+vGC0/p6D3xnkAePI2o0sMyFG966iR5Ki50OI/0mNi2yaRnxfLsPmEZF/JA== - unbox-primitive@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" @@ -26274,11 +25571,16 @@ underscore.string@^3.2.2, underscore.string@~3.3.4: sprintf-js "^1.0.3" util-deprecate "^1.0.2" -underscore@>=1.8.3, underscore@^1.12.1, underscore@^1.13.2, underscore@~1.6.0: +underscore@>=1.8.3, underscore@^1.13.2: version "1.13.6" resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.6.tgz#04786a1f589dc6c09f761fc5f45b89e935136441" integrity sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A== +underscore@~1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.6.0.tgz#8b38b10cacdef63337b8b24e4ff86d45aea529a8" + integrity sha512-z4o1fvKUojIWh9XuaVLUDdf86RQiq13AC1dmHbTpoyuu+bquHms76v16CjycCbec87J7z0k//SiQVk0sMdFmpQ== + unfetch@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/unfetch/-/unfetch-4.2.0.tgz#7e21b0ef7d363d8d9af0fb929a5555f6ef97a3be" @@ -26386,13 +25688,6 @@ unique-slug@^2.0.0: dependencies: imurmurhash "^0.1.4" -unique-string@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-1.0.0.tgz#9e1057cca851abb93398f8b33ae187b99caec11a" - integrity sha512-ODgiYu03y5g76A1I9Gt0/chLCzQjvzDy7DsZGsLOE/1MrF6wriEskSncj1+/C58Xk/kPZDppSctDybCwOSaGAg== - dependencies: - crypto-random-string "^1.0.0" - unique-string@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d" @@ -26463,6 +25758,11 @@ universalify@^0.1.0: 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.0" resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" @@ -26511,22 +25811,6 @@ update-browserslist-db@^1.0.10: escalade "^3.1.1" picocolors "^1.0.0" -update-notifier@^2.3.0, update-notifier@^2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-2.5.0.tgz#d0744593e13f161e406acb1d9408b72cad08aff6" - integrity sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw== - dependencies: - boxen "^1.2.1" - chalk "^2.0.1" - configstore "^3.0.0" - import-lazy "^2.1.0" - is-ci "^1.0.10" - is-installed-globally "^0.1.0" - is-npm "^1.0.0" - latest-version "^3.0.0" - semver-diff "^2.0.0" - xdg-basedir "^3.0.0" - update-notifier@^5.0.1: version "5.1.0" resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-5.1.0.tgz#4ab0d7c7f36a231dd7316cf7729313f0214d9ad9" @@ -26573,6 +25857,21 @@ url-loader@^4.1.1: mime-types "^2.1.27" schema-utils "^3.0.0" +url-parse-lax@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" + integrity sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ== + dependencies: + prepend-http "^2.0.0" + +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.0" resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" @@ -26682,12 +25981,12 @@ uuid-browser@^3.1.0: resolved "https://registry.yarnpkg.com/uuid-browser/-/uuid-browser-3.1.0.tgz#0f05a40aef74f9e5951e20efbf44b11871e56410" integrity sha1-DwWkCu90+eWVHiDvv0SxGHHlZBA= -uuid@^3.3.2, uuid@^3.4.0: +uuid@^3.3.2: version "3.4.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== -uuid@^8.3.0, uuid@^8.3.2: +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== @@ -26706,7 +26005,7 @@ v8-to-istanbul@^8.1.0: convert-source-map "^1.6.0" source-map "^0.7.3" -validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.4: +validate-npm-package-license@^3.0.1: version "3.0.4" resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== @@ -26714,7 +26013,7 @@ validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.4: spdx-correct "^3.0.0" spdx-expression-parse "^3.0.0" -validate-npm-package-name@^3.0.0, validate-npm-package-name@~3.0.0: +validate-npm-package-name@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz#5fa912d81eb7d0c74afc140de7317f0ca7df437e" integrity sha1-X6kS2B630MdK/BQN5zF/DKffQ34= @@ -26929,7 +26228,7 @@ watchpack@^2.3.1, watchpack@^2.4.0: glob-to-regexp "^0.4.1" graceful-fs "^4.1.2" -wcwidth@^1.0.0, wcwidth@^1.0.1: +wcwidth@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" integrity sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg== @@ -27193,12 +26492,7 @@ which-boxed-primitive@^1.0.2: is-string "^1.0.5" is-symbol "^1.0.3" -which-module@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" - integrity sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q== - -which@^1.2.14, which@^1.2.9, which@^1.3.0, which@^1.3.1: +which@^1.2.14, which@^1.2.9, which@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== @@ -27226,13 +26520,6 @@ wide-align@^1.1.2, wide-align@^1.1.5: dependencies: string-width "^1.0.2 || 2 || 3 || 4" -widest-line@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-2.0.1.tgz#7438764730ec7ef4381ce4df82fb98a53142a3fc" - integrity sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA== - dependencies: - string-width "^2.1.1" - widest-line@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca" @@ -27267,7 +26554,7 @@ wordwrap@^1.0.0: resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= -worker-farm@^1.6.0, worker-farm@^1.7.0: +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== @@ -27305,15 +26592,6 @@ workerpool@^6.2.1: resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.3.1.tgz#80a9b76e70556acfb1457a3984f8637717f7cdee" integrity sha512-0x7gJm1rhpn5SPG9NENOxPtbfUZZtK/qOg6gEdSqeDBA3dTeR91RJqSPjccPRCkhNfrnnl/dWxSSj5w9CtdzNA== -wrap-ansi@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" - integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== - dependencies: - ansi-styles "^3.2.0" - string-width "^3.0.0" - strip-ansi "^5.0.0" - wrap-ansi@^6.2.0: version "6.2.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" @@ -27347,7 +26625,7 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= -write-file-atomic@^2.0.0, write-file-atomic@^2.3.0, write-file-atomic@^2.4.3: +write-file-atomic@^2.3.0: version "2.4.3" resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.3.tgz#1fd2e9ae1df3e75b8d8c367443c692d4ca81f481" integrity sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ== @@ -27374,15 +26652,22 @@ write-file-atomic@^4.0.2: imurmurhash "^0.1.4" signal-exit "^3.0.7" -ws@^6.1.0, ws@^7.4.6, ws@~8.2.3: +ws@^6.1.0: + version "6.2.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.2.tgz#dd5cdbd57a9979916097652d78f1cc5faea0c32e" + integrity sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw== + dependencies: + async-limiter "~1.0.0" + +ws@^7.4.6: version "7.5.3" resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.3.tgz#160835b63c7d97bfab418fc1b8a9fced2ac01a74" integrity sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg== -xdg-basedir@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" - integrity sha512-1Dly4xqlulvPD3fZUQJLY+FUIeqN3N2MM3uqe4rCJftAvOjFa3jFGfctOgluGx4ahPbUCsZkmJILiP0Vi4T6lQ== +ws@~8.2.3: + version "8.2.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.2.3.tgz#63a56456db1b04367d0b721a0b80cae6d8becbba" + integrity sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA== xdg-basedir@^4.0.0: version "4.0.0" @@ -27404,11 +26689,6 @@ xmlchars@^2.2.0: resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== -xmlhttprequest-ssl@^1.6.2: - version "1.6.3" - resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.6.3.tgz#03b713873b01659dfa2c1c5d056065b27ddc2de6" - integrity sha512-3XfeQE/wNkvrIktn2Kf0869fC0BN6UpydVasGIeSm2B1Llihf7/0UfZM+eCkOw3P7bP4+qPgqhm7ZoxuJtFU0Q== - xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" @@ -27431,11 +26711,6 @@ y18n@^5.0.5: 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.0, yallist@^3.0.2: version "3.1.1" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" @@ -27464,27 +26739,15 @@ yaml@^2.1.1: resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.1.1.tgz#1e06fb4ca46e60d9da07e4f786ea370ed3c3cfec" integrity sha512-o96x3OPo8GjWeSLF+wOAbrPfhFOGY0W00GNaxCDv+9hkcDJEnev1yh8S7pgHF0ik6zc8sQLuL8hjHjJULZp8bw== -yargs-parser@^15.0.1, yargs-parser@^20.0.0, yargs-parser@^20.2.2, yargs-parser@^20.2.3, yargs-parser@^21.0.0, yargs-parser@~20.2.7: +yargs-parser@^20.0.0, yargs-parser@^20.2.2, yargs-parser@^20.2.3: version "20.2.9" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== -yargs@^14.2.3: - version "14.2.3" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-14.2.3.tgz#1a1c3edced1afb2a2fea33604bc6d1d8d688a414" - integrity sha512-ZbotRWhF+lkjijC/VhmOT9wSgyBQ7+zr13+YLkhfsSiTriYsMzkTUFP18pFhWwBeMa5gUc1MzbhrO6/VB7c9Xg== - dependencies: - cliui "^5.0.0" - decamelize "^1.2.0" - find-up "^3.0.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 "^3.0.0" - which-module "^2.0.0" - y18n "^4.0.0" - yargs-parser "^15.0.1" +yargs-parser@^21.0.0: + 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@^16.2.0: version "16.2.0" From e4944fac892ce3dd078af03783159c730a7a46e3 Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Corvo Date: Thu, 30 Mar 2023 18:31:30 -0700 Subject: [PATCH 103/193] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20Add=20related=20?= =?UTF-8?q?channel=20information=20(#162)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 🎸 Add related channel information --- addons/api/addon/models/session-recording.js | 12 ++++++ .../unit/models/session-recording-test.js | 43 +++++++++++-------- .../session-recordings/session-recording.js | 2 +- .../channels-by-connection/channel.js | 3 +- .../scopes/scope/session-recordings/index.hbs | 2 +- .../channels-by-connection/channel.hbs | 29 +++++++++---- .../session-recording/index.hbs | 9 ++-- 7 files changed, 64 insertions(+), 36 deletions(-) diff --git a/addons/api/addon/models/session-recording.js b/addons/api/addon/models/session-recording.js index 89ee6560d..e2b297054 100644 --- a/addons/api/addon/models/session-recording.js +++ b/addons/api/addon/models/session-recording.js @@ -28,7 +28,19 @@ export default class SessionRecordingModel extends GeneratedSessionRecordingMode return !TYPES_SESSION_RECORDING.includes(this.type); } + /** + * Returns scope name or scope id from the target that belongs to the session recording. + * @type {string} + */ get targetScopeDisplayName() { return this.target?.scope?.name || this.target?.scope?.id; } + + /** + * Returns the user name or user id that belongs to the session recording. + * @type {string} + */ + get userDisplayName() { + return this.user?.name || this.user?.id; + } } diff --git a/addons/api/tests/unit/models/session-recording-test.js b/addons/api/tests/unit/models/session-recording-test.js index af61282a6..d65a3f1c2 100644 --- a/addons/api/tests/unit/models/session-recording-test.js +++ b/addons/api/tests/unit/models/session-recording-test.js @@ -56,32 +56,37 @@ module('Unit | Model | session-recording', function (hooks) { const store = this.owner.lookup('service:store'); const fakeName = 'Scope name'; const fakeId = 's_123456789'; - // Scope models: A has just name, B has just id. - const scopeModelA = await store.createRecord('scope', { - type: 'global', - name: fakeName, - id: 's_1234567890', - }); - const scopeModelB = await store.createRecord('scope', { - type: 'org', - id: fakeId, - }); - - const targetModelA = await store.createRecord('target', { - scope: scopeModelA, - }); - const targetModelB = await store.createRecord('target', { - scope: scopeModelB, - }); const modelA = store.createRecord('session-recording', { - target: targetModelA, + target: { + scope: { name: fakeName, id: fakeId }, + }, }); const modelB = store.createRecord('session-recording', { - target: targetModelB, + target: { + scope: { id: fakeId }, + }, }); assert.strictEqual(modelA.targetScopeDisplayName, fakeName); assert.strictEqual(modelB.targetScopeDisplayName, fakeId); }); + + test('it has userDisplayName and returns the expected values', async function (assert) { + assert.expect(2); + const store = this.owner.lookup('service:store'); + const fakeUserName = 'User name'; + const fakeUserId = 'userid'; + + const userModelA = store.createRecord('session-recording', { + user: { name: fakeUserName, id: fakeUserId }, + }); + + const userModelB = store.createRecord('session-recording', { + user: { id: fakeUserId }, + }); + + assert.strictEqual(userModelA.userDisplayName, fakeUserName); + assert.strictEqual(userModelB.userDisplayName, fakeUserId); + }); }); diff --git a/ui/admin/app/controllers/scopes/scope/session-recordings/session-recording.js b/ui/admin/app/controllers/scopes/scope/session-recordings/session-recording.js index cf762b744..732c8432e 100644 --- a/ui/admin/app/controllers/scopes/scope/session-recordings/session-recording.js +++ b/ui/admin/app/controllers/scopes/scope/session-recordings/session-recording.js @@ -10,6 +10,6 @@ export default class ScopesScopeSessionRecordingsSessionRecordingController exte * Session recording breadcrumb */ get breadCrumb() { - return this.model.displayName; + return this.model.sessionRecording.displayName; } } diff --git a/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.js b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.js index 57fc48f2e..c05d6f907 100644 --- a/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.js +++ b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.js @@ -7,7 +7,7 @@ export default class ScopesScopeSessionRecordingsSessionRecordingChannelsByConne // =methods async model({ channel_id }) { - const sessionRecording = await this.modelFor( + const { sessionRecording, storageBucket } = await this.modelFor( 'scopes.scope.session-recordings.session-recording' ); const channelRecording = await this.store.peekRecord( @@ -21,6 +21,7 @@ export default class ScopesScopeSessionRecordingsSessionRecordingChannelsByConne return { channelRecording, sessionRecording, + storageBucket, asciicast: asciicast, }; } diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs index 3e181c407..38b75519a 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs @@ -34,7 +34,7 @@ class='session-recording-list-cell-item hds-font-weight-semibold' > - {{B.data.user.name}} + {{B.data.userDisplayName}}
{{! Target }} diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs index e9e9ce63d..f2054ee48 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs @@ -17,6 +17,7 @@ + {{! Channel details information }}

{{t 'resources.session-recording.channel.details'}}

{{! Start time }} @@ -25,12 +26,6 @@ {{@model.channelRecording.start_time}}

- {{! Created By }} -

- - {{@model.sessionRecording.user.name}} -

- {{! Type }}

@@ -54,11 +49,27 @@ {{format-bytes-size @model.channelRecording.bytes_down}}

+
- {{! Errors }} + {{! Channel related information }} +
+

{{t 'resources.session-recording.related'}}

+ {{! User name }}

- - {{@model.channelRecording.errors}} + + {{#if @model.sessionRecording.user}} + {{@model.sessionRecording.userDisplayName}} + {{/if}} +

+ {{! Target name }} +

+ + {{@model.sessionRecording.target.name}} +

+ {{! Bucket name }} +

+ + {{@model.storageBucket.name}}

diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs index 6eaebe465..fb69f47f7 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs @@ -111,7 +111,9 @@ {{! User name }}

- {{@model.sessionRecording.user.name}} + {{#if @model.sessionRecording.user}} + {{@model.sessionRecording.userDisplayName}} + {{/if}}

{{! Target name }}

@@ -121,10 +123,7 @@ {{! Bucket name }}

- {{or - @model.storageBucket.name - (t 'resources.storage-bucket.title') - }} + {{@model.storageBucket.name}}

From 02d8b7e77ce14d694edcafafba29c1877ea94abd Mon Sep 17 00:00:00 2001 From: Dharini Jeeva Date: Fri, 31 Mar 2023 10:14:19 -0700 Subject: [PATCH 104/193] =?UTF-8?q?fix:=20=F0=9F=90=9B=20target=20enable?= =?UTF-8?q?=20session=20recording=20=20(#172)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: πŸ› target enable session recording save * fix: πŸ› remove from adapter --- addons/api/mirage/route-handlers/target.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/api/mirage/route-handlers/target.js b/addons/api/mirage/route-handlers/target.js index 5d7897ee2..81b99b254 100644 --- a/addons/api/mirage/route-handlers/target.js +++ b/addons/api/mirage/route-handlers/target.js @@ -101,8 +101,8 @@ export function targetHandler({ targets }, { params: { idMethod } }) { } } - if (method === 'add-storage-bucket') { - updatedAttrs.storage_bucket_id = attrs.storage_bucket_id; + if (method === 'set-storage-bucket') { + updatedAttrs.storage_bucket_id = attrs.storageBucketId; } if (method === 'remove-storage-bucket') { From 8c01ec2f20d2eac44c771572ae0277bb3fb9332e Mon Sep 17 00:00:00 2001 From: Cameron Perera Date: Fri, 31 Mar 2023 14:10:36 -0500 Subject: [PATCH 105/193] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20update=20player?= =?UTF-8?q?=20to=20allow=20routing=20to=20provided=20route=20(#173)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit βœ… Closes: ICU-8381 --- .../components/session-recording/player/index.hbs | 3 ++- .../channels-by-connection/channel.hbs | 6 +++++- .../channels-by-connection/channel-test.js | 12 +++++++++++- .../components/session-recording/player-test.js | 2 +- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/ui/admin/app/components/session-recording/player/index.hbs b/ui/admin/app/components/session-recording/player/index.hbs index e3244d9bd..eed4493a5 100644 --- a/ui/admin/app/components/session-recording/player/index.hbs +++ b/ui/admin/app/components/session-recording/player/index.hbs @@ -3,7 +3,8 @@
diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs index f2054ee48..db8e1ca49 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs @@ -13,7 +13,11 @@ - + diff --git a/ui/admin/tests/acceptance/session-recordings/session-recording/channels-by-connection/channel-test.js b/ui/admin/tests/acceptance/session-recordings/session-recording/channels-by-connection/channel-test.js index a971cdb27..3d0decb09 100644 --- a/ui/admin/tests/acceptance/session-recordings/session-recording/channels-by-connection/channel-test.js +++ b/ui/admin/tests/acceptance/session-recordings/session-recording/channels-by-connection/channel-test.js @@ -1,5 +1,5 @@ import { module, test } from 'qunit'; -import { visit, currentURL } from '@ember/test-helpers'; +import { visit, currentURL, click } from '@ember/test-helpers'; import { setupApplicationTest } from 'admin/tests/helpers'; import setupMirage from 'ember-cli-mirage/test-support/setup-mirage'; import { authenticateSession } from 'ember-simple-auth/test-support'; @@ -59,5 +59,15 @@ module( await visit(urls.connectionRecording); assert.strictEqual(currentURL(), urls.connectionRecording); }); + + test('user can navigate back to session recording screen', async function (assert) { + assert.expect(1); + // Visit channel + await visit(urls.connectionRecording); + // click "Back to channels" link in player header + await click('.session-recording-player-header > a'); + + assert.strictEqual(currentURL(), urls.sessionRecording); + }); } ); diff --git a/ui/admin/tests/integration/components/session-recording/player-test.js b/ui/admin/tests/integration/components/session-recording/player-test.js index fc93a81f5..9380b7e36 100644 --- a/ui/admin/tests/integration/components/session-recording/player-test.js +++ b/ui/admin/tests/integration/components/session-recording/player-test.js @@ -26,7 +26,7 @@ module('Integration | Component | session-recording/player', function (hooks) { [3.63678, "o", "t"]`; await render(hbs` - + `); assert.dom(this.element).hasText('Back to channels --:----:--'); From 3bf2620b2ccb1086d6411ec9b684148d3b598b3f Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Corvo Date: Fri, 31 Mar 2023 13:55:58 -0700 Subject: [PATCH 106/193] Feat get asciicast from model (#175) * Get the asciicast from the model --- .../session-recording/channels-by-connection/channel.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.js b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.js index c05d6f907..611a762dc 100644 --- a/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.js +++ b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.js @@ -14,15 +14,13 @@ export default class ScopesScopeSessionRecordingsSessionRecordingChannelsByConne 'channel-recording', channel_id ); - - const response = await fetch('/session.cast'); - const asciicast = await response.text(); + const asciicast = await channelRecording.getAsciicast(); return { channelRecording, sessionRecording, storageBucket, - asciicast: asciicast, + asciicast, }; } } From 62ec3fe914d59a073db17fd75ebce71fe5ce40a8 Mon Sep 17 00:00:00 2001 From: Zhihe Li Date: Fri, 31 Mar 2023 17:19:46 -0400 Subject: [PATCH 107/193] =?UTF-8?q?refactor:=20=F0=9F=92=A1=20Add=20channe?= =?UTF-8?q?l=20ability=20for=20asciicasts=20(#174)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/addon/abilities/channel-recording.js | 26 + .../api/addon/abilities/session-recording.js | 2 +- .../api/addon/adapters/session-recording.js | 3 +- addons/api/addon/models/channel-recording.js | 12 +- .../api/addon/models/connection-recording.js | 4 +- addons/api/addon/models/session-recording.js | 2 +- addons/api/app/abilities/channel-recording.js | 6 + addons/api/app/abilities/session-recording.js | 7 +- .../generated/factories/channel-recording.js | 3 +- .../unit/abilities/channel-recording-test.js | 73 + .../unit/abilities/session-recording-test.js | 84 + .../unit/models/channel-recording-test.js | 14 + .../unit/abilities/session-recording-test.js | 64 - yarn.lock | 2343 +++++++++++------ 14 files changed, 1783 insertions(+), 860 deletions(-) create mode 100644 addons/api/addon/abilities/channel-recording.js create mode 100644 addons/api/app/abilities/channel-recording.js create mode 100644 addons/api/tests/unit/abilities/channel-recording-test.js create mode 100644 addons/api/tests/unit/abilities/session-recording-test.js diff --git a/addons/api/addon/abilities/channel-recording.js b/addons/api/addon/abilities/channel-recording.js new file mode 100644 index 000000000..fb6676466 --- /dev/null +++ b/addons/api/addon/abilities/channel-recording.js @@ -0,0 +1,26 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import ModelAbility from './model'; +import { inject as service } from '@ember/service'; + +/** + * Provides abilities for channel recordings. + */ +export default class ChannelRecordingAbility extends ModelAbility { + // =services + @service abilities; + + // =permissions + get canDownloadAsciicast() { + const sessionRecording = this.model.connection_recording.session_recording; + const sessionRecordingAbility = this.abilities.abilityFor( + 'session-recording', + sessionRecording + ); + + return this.model.isAsciicast && sessionRecordingAbility.canDownload; + } +} diff --git a/addons/api/addon/abilities/session-recording.js b/addons/api/addon/abilities/session-recording.js index 6cd22ba84..1e6360092 100644 --- a/addons/api/addon/abilities/session-recording.js +++ b/addons/api/addon/abilities/session-recording.js @@ -28,7 +28,7 @@ export default class SessionRecordingAbility extends ModelAbility { ); } - get canDownloadAsciiCast() { + get canDownload() { return this.model.isSSH && this.hasAuthorizedAction('download'); } } diff --git a/addons/api/addon/adapters/session-recording.js b/addons/api/addon/adapters/session-recording.js index 0531baa3a..38f992bdc 100644 --- a/addons/api/addon/adapters/session-recording.js +++ b/addons/api/addon/adapters/session-recording.js @@ -1,4 +1,5 @@ import ApplicationAdapter from './application'; +import { MIME_TYPE_ASCIICAST } from 'api/models/channel-recording'; export default class SessionRecordingAdapter extends ApplicationAdapter { /** @@ -49,7 +50,7 @@ export default class SessionRecordingAdapter extends ApplicationAdapter { getAsciicast(id) { return this.getRecordingDownload({ id, - mimeType: 'application/x-asciicast', + mimeType: MIME_TYPE_ASCIICAST, }); } } diff --git a/addons/api/addon/models/channel-recording.js b/addons/api/addon/models/channel-recording.js index 993a5d69b..c1696f9f0 100644 --- a/addons/api/addon/models/channel-recording.js +++ b/addons/api/addon/models/channel-recording.js @@ -1,8 +1,18 @@ import GeneratedChannelRecordingModel from '../generated/models/channel-recording'; import { belongsTo } from '@ember-data/model'; +export const MIME_TYPE_ASCIICAST = 'application/x-asciicast'; + export default class ChannelRecordingModel extends GeneratedChannelRecordingModel { - @belongsTo('connection-recording') connection_recording; + @belongsTo('connection-recording', { async: false }) connection_recording; + + /** + * True if the channel supports asciicast. + * @type {boolean} + */ + get isAsciicast() { + return this.mime_types.includes(MIME_TYPE_ASCIICAST); + } /** * Download the ascii cast recording for this channel. diff --git a/addons/api/addon/models/connection-recording.js b/addons/api/addon/models/connection-recording.js index 58ee85449..ae0022191 100644 --- a/addons/api/addon/models/connection-recording.js +++ b/addons/api/addon/models/connection-recording.js @@ -2,6 +2,6 @@ import GeneratedConnectionRecordingModel from '../generated/models/connection-re import { belongsTo, hasMany } from '@ember-data/model'; export default class ConnectionRecordingModel extends GeneratedConnectionRecordingModel { - @belongsTo('session-recording') session_recording; - @hasMany('channel-recording') channel_recordings; + @belongsTo('session-recording', { async: false }) session_recording; + @hasMany('channel-recording', { async: false }) channel_recordings; } diff --git a/addons/api/addon/models/session-recording.js b/addons/api/addon/models/session-recording.js index e2b297054..666009455 100644 --- a/addons/api/addon/models/session-recording.js +++ b/addons/api/addon/models/session-recording.js @@ -8,7 +8,7 @@ export const TYPES_SESSION_RECORDING = Object.freeze([ ]); export default class SessionRecordingModel extends GeneratedSessionRecordingModel { - @hasMany('connection-recording') connection_recordings; + @hasMany('connection-recording', { async: false }) connection_recordings; @service store; diff --git a/addons/api/app/abilities/channel-recording.js b/addons/api/app/abilities/channel-recording.js new file mode 100644 index 000000000..75aa2fd3c --- /dev/null +++ b/addons/api/app/abilities/channel-recording.js @@ -0,0 +1,6 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +export { default } from 'api/abilities/channel-recording'; diff --git a/addons/api/app/abilities/session-recording.js b/addons/api/app/abilities/session-recording.js index a6d654ffd..07dbc7fe0 100644 --- a/addons/api/app/abilities/session-recording.js +++ b/addons/api/app/abilities/session-recording.js @@ -1,3 +1,6 @@ -import { Ability } from 'ember-can'; +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ -export default class extends Ability {} +export { default } from 'api/abilities/session-recording'; diff --git a/addons/api/mirage/generated/factories/channel-recording.js b/addons/api/mirage/generated/factories/channel-recording.js index 58980d2c2..6c9b2875d 100644 --- a/addons/api/mirage/generated/factories/channel-recording.js +++ b/addons/api/mirage/generated/factories/channel-recording.js @@ -5,6 +5,7 @@ import { Factory } from 'miragejs'; import { faker } from '@faker-js/faker'; +import { MIME_TYPE_ASCIICAST } from 'api/models/channel-recording'; /** * GeneratedChannelRecordingModelFactory @@ -20,5 +21,5 @@ export default Factory.extend({ }, end_time: () => faker.date.recent(), duration: () => `${faker.datatype.number()}s`, - mime_types: () => ['application/x-asciicast'], + mime_types: () => [MIME_TYPE_ASCIICAST], }); diff --git a/addons/api/tests/unit/abilities/channel-recording-test.js b/addons/api/tests/unit/abilities/channel-recording-test.js new file mode 100644 index 000000000..dff28858d --- /dev/null +++ b/addons/api/tests/unit/abilities/channel-recording-test.js @@ -0,0 +1,73 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; +import { MIME_TYPE_ASCIICAST } from 'api/models/channel-recording'; +import { TYPE_SESSION_RECORDING_SSH } from 'api/models/session-recording'; + +module('Unit | Ability | channel-recording', function (hooks) { + setupTest(hooks); + + let canService; + let store; + + hooks.beforeEach(function () { + canService = this.owner.lookup('service:can'); + store = this.owner.lookup('service:store'); + }); + + test('it exists', function (assert) { + const ability = this.owner.lookup('ability:channel-recording'); + assert.ok(ability); + }); + + test('it can download asciicast', function (assert) { + assert.expect(1); + + const sessionRecordingModel = store.createRecord('session-recording', { + authorized_actions: ['download'], + type: TYPE_SESSION_RECORDING_SSH, + }); + const connectionRecordingModel = store.createRecord( + 'connection-recording', + { + session_recording: sessionRecordingModel, + } + ); + const channelRecordingModel = store.createRecord('channel-recording', { + mime_types: [MIME_TYPE_ASCIICAST], + connection_recording: connectionRecordingModel, + }); + + assert.true( + canService.can( + 'downloadAsciicast channel-recording', + channelRecordingModel + ) + ); + }); + + test('it cannot download asciicast without the correct mime type', function (assert) { + assert.expect(1); + + const sessionRecordingModel = store.createRecord('session-recording', { + authorized_actions: ['download'], + type: TYPE_SESSION_RECORDING_SSH, + }); + const connectionRecordingModel = store.createRecord( + 'connection-recording', + { + session_recording: sessionRecordingModel, + } + ); + const channelRecordingModel = store.createRecord('channel-recording', { + mime_types: ['unknown'], + connection_recording: connectionRecordingModel, + }); + + assert.false( + canService.can( + 'downloadAsciicast channel-recording', + channelRecordingModel + ) + ); + }); +}); diff --git a/addons/api/tests/unit/abilities/session-recording-test.js b/addons/api/tests/unit/abilities/session-recording-test.js new file mode 100644 index 000000000..729aebd07 --- /dev/null +++ b/addons/api/tests/unit/abilities/session-recording-test.js @@ -0,0 +1,84 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; +import { TYPE_SESSION_RECORDING_SSH } from 'api/models/session-recording'; + +module('Unit | Ability | session-recording', function (hooks) { + setupTest(hooks); + + let canService; + let store; + + hooks.beforeEach(function () { + canService = this.owner.lookup('service:can'); + store = this.owner.lookup('service:store'); + }); + + test('it exists', function (assert) { + const ability = this.owner.lookup('ability:session-recording'); + assert.ok(ability); + }); + + test('can download when an ssh recording has download authorization', function (assert) { + assert.expect(2); + + const recordingWithAuthorizedAction = store.createRecord( + 'session-recording', + { + authorized_actions: ['download'], + type: TYPE_SESSION_RECORDING_SSH, + } + ); + const recordingWithoutAuthorizedAction = store.createRecord( + 'session-recording', + { + authorized_actions: [], + type: TYPE_SESSION_RECORDING_SSH, + } + ); + + assert.true( + canService.can( + 'download session-recording', + recordingWithAuthorizedAction + ) + ); + assert.false( + canService.can( + 'download session-recording', + recordingWithoutAuthorizedAction + ) + ); + }); + + test('cannot download when a recording is not ssh type', function (assert) { + assert.expect(2); + + const recordingWithAuthorizedAction = store.createRecord( + 'session-recording', + { + authorized_actions: ['download'], + type: 'unknown', + } + ); + const recordingWithoutAuthorizedAction = store.createRecord( + 'session-recording', + { + authorized_actions: [], + type: 'unknown', + } + ); + + assert.false( + canService.can( + 'download session-recording', + recordingWithAuthorizedAction + ) + ); + assert.false( + canService.can( + 'download session-recording', + recordingWithoutAuthorizedAction + ) + ); + }); +}); diff --git a/addons/api/tests/unit/models/channel-recording-test.js b/addons/api/tests/unit/models/channel-recording-test.js index 2ec3d2427..9cf91b116 100644 --- a/addons/api/tests/unit/models/channel-recording-test.js +++ b/addons/api/tests/unit/models/channel-recording-test.js @@ -1,5 +1,6 @@ import { module, test } from 'qunit'; import { setupTest } from 'ember-qunit'; +import { MIME_TYPE_ASCIICAST } from 'api/models/channel-recording'; module('Unit | Model | channel-recording', function (hooks) { setupTest(hooks); @@ -9,4 +10,17 @@ module('Unit | Model | channel-recording', function (hooks) { let model = store.createRecord('channel-recording', {}); assert.ok(model); }); + + test('it has isAsciicast property and returns the expected values', async function (assert) { + assert.expect(2); + const store = this.owner.lookup('service:store'); + const modelA = store.createRecord('channel-recording', { + mime_types: [MIME_TYPE_ASCIICAST], + }); + const modelB = store.createRecord('channel-recording', { + mime_types: ['random'], + }); + assert.true(modelA.isAsciicast); + assert.false(modelB.isAsciicast); + }); }); diff --git a/ui/admin/tests/unit/abilities/session-recording-test.js b/ui/admin/tests/unit/abilities/session-recording-test.js index 027d716bc..fd4f49b4f 100644 --- a/ui/admin/tests/unit/abilities/session-recording-test.js +++ b/ui/admin/tests/unit/abilities/session-recording-test.js @@ -202,68 +202,4 @@ module('Unit | Abilities | session-recording', function (hooks) { ) ); }); - - test('can download asciicast when an ssh recording has download authorization', function (assert) { - assert.expect(2); - - const recordingWithAuthorizedAction = store.createRecord( - 'session-recording', - { - authorized_actions: ['download'], - type: TYPE_SESSION_RECORDING_SSH, - } - ); - const recordingWithoutAuthorizedAction = store.createRecord( - 'session-recording', - { - authorized_actions: [], - type: TYPE_SESSION_RECORDING_SSH, - } - ); - - assert.true( - canService.can( - 'downloadAsciiCast session-recording', - recordingWithAuthorizedAction - ) - ); - assert.false( - canService.can( - 'downloadAsciiCast session-recording', - recordingWithoutAuthorizedAction - ) - ); - }); - - test('cannot download asciicast when a recording is not ssh type', function (assert) { - assert.expect(2); - - const recordingWithAuthorizedAction = store.createRecord( - 'session-recording', - { - authorized_actions: ['download'], - type: 'unknown', - } - ); - const recordingWithoutAuthorizedAction = store.createRecord( - 'session-recording', - { - authorized_actions: [], - type: 'unknown', - } - ); - - assert.false( - canService.can( - 'downloadAsciiCast session-recording', - recordingWithAuthorizedAction - ) - ); - assert.false( - canService.can( - 'downloadAsciiCast session-recording', - recordingWithoutAuthorizedAction - ) - ); - }); }); diff --git a/yarn.lock b/yarn.lock index 07b43c7a1..c8d99277f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4492,17 +4492,17 @@ resolved "https://registry.yarnpkg.com/@glimmer/env/-/env-0.1.7.tgz#fd2d2b55a9029c6b37a6c935e8c8871ae70dfa07" integrity sha1-/S0rVakCnGs3psk16MiHGucN+gc= -"@glimmer/global-context@0.83.1": - version "0.83.1" - resolved "https://registry.yarnpkg.com/@glimmer/global-context/-/global-context-0.83.1.tgz#3e2d97f10ff623bcfb5b7dc29a858d546a6c6d66" - integrity sha512-OwlgqpbOJU73EjZOZdftab0fKbtdJ4x/QQeJseL9cvaAUiK3+w52M5ONFxD1T/yPBp2Mf7NCYqA/uL8tRbzY2A== +"@glimmer/global-context@0.84.3": + version "0.84.3" + resolved "https://registry.yarnpkg.com/@glimmer/global-context/-/global-context-0.84.3.tgz#f8bf2cda9562716f2ddf3f96837e7559600635c4" + integrity sha512-8Oy9Wg5IZxMEeAnVmzD2NkObf89BeHoFSzJgJROE/deutd3rxg83mvlOez4zBBGYwnTb+VGU2LYRpet92egJjA== dependencies: "@glimmer/env" "^0.1.7" -"@glimmer/interfaces@0.83.1": - version "0.83.1" - resolved "https://registry.yarnpkg.com/@glimmer/interfaces/-/interfaces-0.83.1.tgz#fb16f5f683ddc55f130887b6141f58c0751350fe" - integrity sha512-rjAztghzX97v8I4rk3+NguM3XGYcFjc/GbJ8qrEj19KF2lUDoDBW1sB7f0tov3BD5HlrGXei/vOh4+DHfjeB5w== +"@glimmer/interfaces@0.84.3": + version "0.84.3" + resolved "https://registry.yarnpkg.com/@glimmer/interfaces/-/interfaces-0.84.3.tgz#629777a4abe373b0785656f6c8d08989f5784805" + integrity sha512-dk32ykoNojt0mvEaIW6Vli5MGTbQo58uy3Epj7ahCgTHmWOKuw/0G83f2UmFprRwFx689YTXG38I/vbpltEjzg== dependencies: "@simple-dom/interface" "^1.4.0" @@ -4532,16 +4532,16 @@ dependencies: "@glimmer/util" "^0.42.2" -"@glimmer/reference@^0.83.1": - version "0.83.1" - resolved "https://registry.yarnpkg.com/@glimmer/reference/-/reference-0.83.1.tgz#0345b95431b5bb19843b308e6311d1ef81e36192" - integrity sha512-BThEwDlMkJB1WBPWDrww+VxgGyDbwxh5FFPvGhkovvCZnCb7fAMUCt9pi6CUZtviugkWOBFtE9P4eZZbOLkXeg== +"@glimmer/reference@^0.84.3": + version "0.84.3" + resolved "https://registry.yarnpkg.com/@glimmer/reference/-/reference-0.84.3.tgz#6420ad9c102633ac83939fd1b2457269d21fb632" + integrity sha512-lV+p/aWPVC8vUjmlvYVU7WQJsLh319SdXuAWoX/SE3pq340BJlAJiEcAc6q52y9JNhT57gMwtjMX96W5Xcx/qw== dependencies: "@glimmer/env" "^0.1.7" - "@glimmer/global-context" "0.83.1" - "@glimmer/interfaces" "0.83.1" - "@glimmer/util" "0.83.1" - "@glimmer/validator" "0.83.1" + "@glimmer/global-context" "0.84.3" + "@glimmer/interfaces" "0.84.3" + "@glimmer/util" "0.84.3" + "@glimmer/validator" "0.84.3" "@glimmer/runtime@^0.42.1": version "0.42.2" @@ -4566,13 +4566,13 @@ handlebars "^4.0.13" simple-html-tokenizer "^0.5.8" -"@glimmer/syntax@^0.83.1": - version "0.83.1" - resolved "https://registry.yarnpkg.com/@glimmer/syntax/-/syntax-0.83.1.tgz#7e18dd445871c157ba0281f12a4fbf316fa49b41" - integrity sha512-n3vEd0GtjtgkOsd2gqkSimp8ecqq5KrHyana/s1XJZvVAPD5rMWT9WvAVWG8XAktns8BxjwLIUoj/vkOfA+eHg== +"@glimmer/syntax@^0.84.3": + version "0.84.3" + resolved "https://registry.yarnpkg.com/@glimmer/syntax/-/syntax-0.84.3.tgz#4045a1708cef7fd810cff42fe6deeba40c7286d0" + integrity sha512-ioVbTic6ZisLxqTgRBL2PCjYZTFIwobifCustrozRU2xGDiYvVIL0vt25h2c1ioDsX59UgVlDkIK4YTAQQSd2A== dependencies: - "@glimmer/interfaces" "0.83.1" - "@glimmer/util" "0.83.1" + "@glimmer/interfaces" "0.84.3" + "@glimmer/util" "0.84.3" "@handlebars/parser" "~2.0.0" simple-html-tokenizer "^0.5.11" @@ -4592,13 +4592,13 @@ "@glimmer/env" "^0.1.7" "@glimmer/validator" "^0.44.0" -"@glimmer/util@0.83.1": - version "0.83.1" - resolved "https://registry.yarnpkg.com/@glimmer/util/-/util-0.83.1.tgz#cc7511b03164d658cf6e3262fce5a0fcb82edceb" - integrity sha512-amvjtl9dvrkxsoitXAly9W5NUaLIE3A2J2tWhBWIL1Z6DOFotfX7ytIosOIcPhJLZCtiXPHzMutQRv0G/MSMsA== +"@glimmer/util@0.84.3": + version "0.84.3" + resolved "https://registry.yarnpkg.com/@glimmer/util/-/util-0.84.3.tgz#9ae0166982c0b48aa94b02d6ba8c2c81976ade4b" + integrity sha512-qFkh6s16ZSRuu2rfz3T4Wp0fylFj3HBsONGXQcrAdZjdUaIS6v3pNj6mecJ71qRgcym9Hbaq/7/fefIwECUiKw== dependencies: "@glimmer/env" "0.1.7" - "@glimmer/interfaces" "0.83.1" + "@glimmer/interfaces" "0.84.3" "@simple-dom/interface" "^1.4.0" "@glimmer/util@^0.42.2": @@ -4611,13 +4611,13 @@ resolved "https://registry.yarnpkg.com/@glimmer/util/-/util-0.44.0.tgz#45df98d73812440206ae7bda87cfe04aaae21ed9" integrity sha512-duAsm30uVK9jSysElCbLyU6QQYO2X9iLDLBIBUcCqck9qN1o3tK2qWiHbGK5d6g8E2AJ4H88UrfElkyaJlGrwg== -"@glimmer/validator@0.83.1", "@glimmer/validator@^0.83.0": - version "0.83.1" - resolved "https://registry.yarnpkg.com/@glimmer/validator/-/validator-0.83.1.tgz#7578cb2284f728c8e9302c51fc6e7660b570ac54" - integrity sha512-LaILSNnQgDHZpaUsfjVndbS1JfVn0xdTlJdFJblPbhoVklOBSReZVekens3EQ6xOr3BC612sRm1hBnEPixOY6A== +"@glimmer/validator@0.84.3", "@glimmer/validator@^0.84.3": + version "0.84.3" + resolved "https://registry.yarnpkg.com/@glimmer/validator/-/validator-0.84.3.tgz#cd83b7f9ab78953f23cc11a32d83d7f729c54df2" + integrity sha512-RTBV4TokUB0vI31UC7ikpV7lOYpWUlyqaKV//pRC4pexYMlmqnVhkFrdiimB/R1XyNdUOQUmnIAcdic39NkbhQ== dependencies: "@glimmer/env" "^0.1.7" - "@glimmer/global-context" "0.83.1" + "@glimmer/global-context" "0.84.3" "@glimmer/validator@^0.44.0": version "0.44.0" @@ -4659,6 +4659,32 @@ resolved "https://registry.yarnpkg.com/@handlebars/parser/-/parser-2.0.0.tgz#5e8b7298f31ff8f7b260e6b7363c7e9ceed7d9c5" integrity sha512-EP9uEDZv/L5Qh9IWuMUGJRfwhXJ4h1dqKTT4/3+tY0eu7sPis7xh23j61SYUnNF4vqCQvvUXpDo9Bh/+q1zASA== +"@hapi/b64@5.x.x": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@hapi/b64/-/b64-5.0.0.tgz#b8210cbd72f4774985e78569b77e97498d24277d" + integrity sha512-ngu0tSEmrezoiIaNGG6rRvKOUkUuDdf4XTPnONHGYfSGRmDqPZX5oJL6HAdKTo1UQHECbdB4OzhWrfgVppjHUw== + dependencies: + "@hapi/hoek" "9.x.x" + +"@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/cryptiles@5.x.x": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@hapi/cryptiles/-/cryptiles-5.1.0.tgz#655de4cbbc052c947f696148c83b187fc2be8f43" + integrity sha512-fo9+d1Ba5/FIoMySfMqPBR/7Pa29J2RsiPrl7bkwo5W5o+AN1dAYQRi4SPrPwwVxVGKjgLOEWrsvt1BonJSfLA== + 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== + "@hashicorp/design-system-components@^1.5.1": version "1.5.1" resolved "https://registry.yarnpkg.com/@hashicorp/design-system-components/-/design-system-components-1.5.1.tgz#ed02dd834db2d254f2dc6c108f3520ddf3268de3" @@ -4737,6 +4763,14 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== +"@iarna/cli@^2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@iarna/cli/-/cli-2.1.0.tgz#f830356d54c72c804bd7afc43999de31e40fc3d6" + integrity sha512-rvVVqDa2g860niRbqs3D5RhL4la3dc1vwk+NlpKPZxKaMSHtE2se6C2x8NeveN+rcjp3/686X+u+09CZ+7lmAQ== + dependencies: + glob "^7.1.2" + signal-exit "^3.0.2" + "@istanbuljs/load-nyc-config@^1.0.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" @@ -5163,6 +5197,11 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" +"@npmcli/ci-detect@^1.0.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@npmcli/ci-detect/-/ci-detect-1.4.0.tgz#18478bbaa900c37bfbd8a2006a6262c62e8b0fe1" + integrity sha512-3BGrt6FLjqM6br5AhWRKTr3u5GIVkjRYeAFrMp3HjnfICrg4xOrVRwFavKT6tsp++bq5dluL5t8ME/Nha/6c1Q== + "@npmcli/fs@^1.0.0": version "1.1.1" resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-1.1.1.tgz#72f719fe935e687c56a4faecf3c03d06ba593257" @@ -5217,11 +5256,6 @@ resolved "https://registry.yarnpkg.com/@simple-dom/interface/-/interface-1.4.0.tgz#e8feea579232017f89b0138e2726facda6fbb71f" integrity sha512-l5qumKFWU0S+4ZzMaLXFU8tQZsicHEMEyAxI5kDFGhJsRqDwe0a7/iPA/GdxlGyDKseQQAgIz5kzU7eXTrlSpA== -"@sindresorhus/is@^0.14.0": - version "0.14.0" - resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" - integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== - "@sindresorhus/is@^4.0.0": version "4.0.1" resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.0.1.tgz#d26729db850fa327b7cacc5522252194404226f5" @@ -7138,13 +7172,6 @@ resolve-from "^5.0.0" store2 "^2.12.0" -"@szmarczak/http-timer@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" - integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA== - dependencies: - defer-to-connect "^1.0.1" - "@szmarczak/http-timer@^4.0.5": version "4.0.6" resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.6.tgz#b4a914bb62e7c272d4e5989fe4440f812ab1d807" @@ -8025,6 +8052,14 @@ resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31" integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ== +JSONStream@^1.3.5: + version "1.3.5" + resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" + integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ== + dependencies: + jsonparse "^1.2.0" + through ">=2.2.7 <3" + JSV@^4.0.x: version "4.0.2" resolved "https://registry.yarnpkg.com/JSV/-/JSV-4.0.2.tgz#d077f6825571f82132f9dffaed587b4029feff57" @@ -8035,7 +8070,7 @@ abab@^2.0.3, abab@^2.0.5: resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== -abbrev@1: +abbrev@1, abbrev@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== @@ -8123,6 +8158,13 @@ address@1.1.2, address@^1.0.1: resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6" integrity sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA== +agent-base@4, agent-base@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee" + integrity sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg== + dependencies: + es6-promisify "^5.0.0" + agent-base@5: version "5.1.1" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-5.1.1.tgz#e8fb3f242959db44d63be665db7a8e739537a32c" @@ -8135,6 +8177,20 @@ agent-base@6, agent-base@^6.0.2: dependencies: debug "4" +agent-base@~4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9" + integrity sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg== + dependencies: + es6-promisify "^5.0.0" + +agentkeepalive@^3.4.1: + version "3.5.2" + resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-3.5.2.tgz#a113924dd3fa24a0bc3b78108c450c2abee00f67" + integrity sha512-e0L/HNe6qkQ7H19kTlRRqUibEAwDK5AFk6y3PtMsuut2VAH6+Q4xZml1tNDJD7kSAyqmbG/K08K5WEJYtUrSlQ== + dependencies: + humanize-ms "^1.2.1" + agentkeepalive@^4.1.3: version "4.2.1" resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.2.1.tgz#a7975cbb9f83b367f06c90cc51ff28fe7d499717" @@ -8249,6 +8305,13 @@ anchor-markdown-header@^0.5.7: dependencies: emoji-regex "~6.1.0" +ansi-align@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-2.0.0.tgz#c36aeccba563b89ceb556f3690f0b1d9e3547f7f" + integrity sha512-TdlOggdA/zURfMYa7ABC66j+oqfMew58KpJMbUlH3bcZP1b+cBHIHDDn5uH9INsxrHBPjsqM0tDB4jPTF/vgJA== + dependencies: + string-width "^2.0.0" + ansi-align@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.0.tgz#b536b371cf687caaef236c18d3e21fe3797467cb" @@ -8278,42 +8341,22 @@ ansi-escapes@^4.2.1, ansi-escapes@^4.3.0: dependencies: type-fest "^0.21.3" -ansi-html@0.0.7, ansi-html@^0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.7.tgz#813584021962a9e9e6fd039f940d12f56ca7859e" - integrity sha512-JoAxEa1DfP9m2xfB/y2r/aKcwXNlltr4+0QSBC4TrLfcxyvepX2Pv0t/xpgGV5bGsDzCYV8SzjWgyCW0T9yYbA== +ansi-html@0.0.7, ansi-html@^0.0.7, ansi-html@^0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.8.tgz#e969db193b12bcdfa6727b29ffd8882dc13cc501" + integrity sha512-QROYz1I1Kj+8bTYgx0IlMBpRSCIU+7GjbE0oH+KF7QKc+qSF8YAlIutN59Db17tXN70Ono9upT9Ht0iG93W7ug== -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - integrity sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA== - -ansi-regex@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.1.tgz#123d6479e92ad45ad897d4054e3c7ca7db4944e1" - integrity sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw== - -ansi-regex@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.1.tgz#164daac87ab2d6f6db3a29875e2d1766582dabed" - integrity sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g== - -ansi-regex@^5.0.0, ansi-regex@^5.0.1: +ansi-regex@^2.0.0, ansi-regex@^3.0.0, ansi-regex@^4.1.0, ansi-regex@^5.0.0, ansi-regex@^5.0.1, ansi-regex@^6.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-regex@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" - integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== - ansi-styles@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= -ansi-styles@^3.0.0, ansi-styles@^3.2.1: +ansi-styles@^3.0.0, ansi-styles@^3.2.0, ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== @@ -8354,6 +8397,16 @@ ansicolors@~0.2.1: resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.2.1.tgz#be089599097b74a5c9c4a84a0cdbcdb62bd87aef" integrity sha1-vgiVmQl7dKXJxKhKDNvNtivYeu8= +ansicolors@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.3.2.tgz#665597de86a9ffe3aa9bfbe6cae5c6ea426b4979" + integrity sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg== + +ansistyles@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/ansistyles/-/ansistyles-0.1.3.tgz#5de60415bda071bb37127854c864f41b23254539" + integrity sha512-6QWEyvMgIXX0eO972y7YPBLSBsq7UWKFAoNNTLGaOJ9bstcEL9sCbcjf96dVfNDdUsRoGOK82vWFJlKApXds7g== + anymatch@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" @@ -8375,16 +8428,21 @@ app-root-dir@^1.0.2: resolved "https://registry.yarnpkg.com/app-root-dir/-/app-root-dir-1.0.2.tgz#38187ec2dea7577fff033ffcb12172692ff6e118" integrity sha1-OBh+wt6nV3//Az/8sSFyaS/24Rg= -aproba@^1.0.3, aproba@^1.1.1: +aproba@^1.0.3, aproba@^1.1.1, aproba@^1.1.2: version "1.2.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== -"aproba@^1.0.3 || ^2.0.0": +"aproba@^1.0.3 || ^2.0.0", "aproba@^1.1.2 || 2", aproba@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== +archy@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" + integrity sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw== + are-we-there-yet@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz#372e0e7bd279d8e94c653aaa1f67200884bf3e1c" @@ -8409,7 +8467,7 @@ are-we-there-yet@~1.1.2: delegates "^1.0.0" readable-stream "^2.0.6" -argparse@^1.0.7, argparse@~1.0.2: +argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== @@ -8576,11 +8634,6 @@ asn1.js@^5.2.0: minimalistic-assert "^1.0.0" safer-buffer "^2.1.0" -asn1@0.1.11: - version "0.1.11" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.1.11.tgz#559be18376d08a4ec4dbe80877d27818639b2df7" - integrity sha512-Fh9zh3G2mZ8qM/kwsiKwL2U2FmXxVsboP4x1mXjnhKHv3SmzaBZoYvxEQJz/YS2gnCgd8xlAVWcZnQyC9qZBsA== - asn1@~0.2.3: version "0.2.4" resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" @@ -8598,11 +8651,6 @@ assert-plus@1.0.0, assert-plus@^1.0.0: resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= -assert-plus@^0.1.5: - version "0.1.5" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.1.5.tgz#ee74009413002d84cec7219c6ac811812e723160" - integrity sha512-brU24g7ryhRwGCI2y+1dGQmQXiZF7TtIj583S96y0jjdajIe6wn8BuXyELYhvD22dtIxDQVFk04YTJwwdwOYJw== - assert@^1.1.1: version "1.5.0" resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb" @@ -8664,11 +8712,6 @@ async-each@^1.0.1: resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== -async-limiter@~1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" - integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== - async-promise-queue@^1.0.3, async-promise-queue@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/async-promise-queue/-/async-promise-queue-1.0.5.tgz#cb23bce9fce903a133946a700cc85f27f09ea49d" @@ -8677,28 +8720,13 @@ async-promise-queue@^1.0.3, async-promise-queue@^1.0.5: async "^2.4.1" debug "^2.6.8" -async@^2.4.1, async@^2.6.2, async@^2.6.4: +async@^2.4.1, async@^2.6.2, async@^2.6.4, async@~0.2.9, async@~1.0.0: version "2.6.4" resolved "https://registry.yarnpkg.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221" integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA== dependencies: lodash "^4.17.14" -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== - -async@~0.9.0: - version "0.9.2" - resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d" - integrity sha512-l6ToIJIotphWahxxHyzK9bnLR6kM4jJIIgLShZeqLY7iboHoGkdgFl7W2/Ivi4SkMJYGKqW8vSuk0uKUj6qsSw== - -async@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/async/-/async-1.0.0.tgz#f8fc04ca3a13784ade9e1641af98578cfbd647a9" - integrity sha512-5mO7DX4CbJzp9zjaFXusQQ4tzKJARjNB1Ih1pVBi8wkbmXy/xzIDgEMXxWePLzt2OdFwaxfneIlT1nCiXubrPQ== - asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" @@ -8732,11 +8760,6 @@ autoprefixer@^9.8.6: postcss "^7.0.32" postcss-value-parser "^4.1.0" -aws-sign2@~0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.5.0.tgz#c57103f7a17fc037f02d7c2e64b602ea223f7d63" - integrity sha512-oqUX0DM5j7aPWPCnpWebiyNIj2wiNI87ZxnOMoGv0aE4TGlBy2N+5iWc6dQ/NOKZaBD2W6PVz8jtOGkWzSC5EA== - aws-sign2@~0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" @@ -9289,7 +9312,7 @@ base-64@^0.1.0: resolved "https://registry.yarnpkg.com/base-64/-/base-64-0.1.0.tgz#780a99c84e7d600260361511c4877613bf24f6bb" integrity sha1-eAqZyE59YAJgNhURxId2E78k9rs= -base64-js@^1.0.2, base64-js@^1.3.1, base64-js@^1.5.1: +base64-js@^1.0.2, base64-js@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== @@ -9343,6 +9366,18 @@ big.js@^5.2.2: resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== +bin-links@^1.1.2, bin-links@^1.1.8: + version "1.1.8" + resolved "https://registry.yarnpkg.com/bin-links/-/bin-links-1.1.8.tgz#bd39aadab5dc4bdac222a07df5baf1af745b2228" + integrity sha512-KgmVfx+QqggqP9dA3iIc5pA4T1qEEEL+hOhOhNPaUm77OTrJoOXE/C05SJLNJe6m/2wUK7F1tDSou7n5TfCDzQ== + dependencies: + bluebird "^3.5.3" + cmd-shim "^3.0.0" + gentle-fs "^2.3.0" + graceful-fs "^4.1.15" + npm-normalize-package-bin "^1.0.0" + write-file-atomic "^2.3.0" + binary-extensions@^1.0.0: version "1.13.1" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" @@ -9365,21 +9400,20 @@ bindings@^1.5.0: dependencies: file-uri-to-path "1.0.0" -bl@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" - integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== +bl@^4.1.0, bl@~1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.3.tgz#1e8dd80142eac80d7158c9dccc047fb620e035e7" + integrity sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww== dependencies: - buffer "^5.5.0" - inherits "^2.0.4" - readable-stream "^3.4.0" + readable-stream "^2.3.5" + safe-buffer "^5.1.1" blank-object@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/blank-object/-/blank-object-1.0.2.tgz#f990793fbe9a8c8dd013fb3219420bec81d5f4b9" integrity sha1-+ZB5P76ajI3QE/syGUIL7IHV9Lk= -bluebird@^3.1.1, bluebird@^3.3.5, bluebird@^3.4.6, bluebird@^3.5.0, bluebird@^3.5.5, bluebird@^3.7.2: +bluebird@^3.1.1, bluebird@^3.3.5, bluebird@^3.4.6, bluebird@^3.5.0, bluebird@^3.5.1, bluebird@^3.5.3, 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== @@ -9422,7 +9456,7 @@ body@^5.1.0: raw-body "~1.1.0" safe-json-parse "~1.0.1" -boolbase@^1.0.0, boolbase@~1.0.0: +boolbase@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= @@ -9437,12 +9471,12 @@ boolean@^3.1.4: resolved "https://registry.yarnpkg.com/boolean/-/boolean-3.2.0.tgz#9e5294af4e98314494cbb17979fa54ca159f116b" integrity sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw== -boom@0.4.x: - version "0.4.2" - resolved "https://registry.yarnpkg.com/boom/-/boom-0.4.2.tgz#7a636e9ded4efcefb19cef4947a3c67dfaee911b" - integrity sha512-OvfN8y1oAxxphzkl2SnCS+ztV/uVKTATtgLjWYg/7KwcNyf3rzpHxNQJZCKtsZd4+MteKczhWbSjtEX4bGgU9g== +boom@7.x.x: + version "7.3.0" + resolved "https://registry.yarnpkg.com/boom/-/boom-7.3.0.tgz#733a6d956d33b0b1999da3fe6c12996950d017b9" + integrity sha512-Swpoyi2t5+GhOEGw8rEsKvTxFLIDiiKoUc2gsoV6Lyr43LHBIzch3k2MvYUs8RTROrIkVJ3Al0TkaOGjnb+B6A== dependencies: - hoek "0.9.x" + hoek "6.x.x" bower-config@^1.4.3: version "1.4.3" @@ -9461,6 +9495,19 @@ bower-endpoint-parser@0.2.2: resolved "https://registry.yarnpkg.com/bower-endpoint-parser/-/bower-endpoint-parser-0.2.2.tgz#00b565adbfab6f2d35addde977e97962acbcb3f6" integrity sha1-ALVlrb+rby01rd3pd+l5Yqy8s/Y= +boxen@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b" + integrity sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw== + dependencies: + ansi-align "^2.0.0" + camelcase "^4.0.0" + chalk "^2.0.1" + cli-boxes "^1.0.0" + string-width "^2.0.0" + term-size "^1.2.0" + widest-line "^2.0.0" + boxen@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/boxen/-/boxen-4.2.0.tgz#e411b62357d6d6d36587c8ac3d5d974daa070e64" @@ -10194,17 +10241,7 @@ browserify-zlib@^0.2.0: dependencies: pako "~1.0.5" -browserslist@4.14.2: - version "4.14.2" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.14.2.tgz#1b3cec458a1ba87588cc5e9be62f19b6d48813ce" - integrity sha512-HI4lPveGKUR0x2StIz+2FXfDk9SfVMrxn6PLh1JeGUwcuoDkdKZebWiyLRJ68iIPDpMI4JLVDf7S7XzslgWOhw== - dependencies: - caniuse-lite "^1.0.30001125" - electron-to-chromium "^1.3.564" - escalade "^3.0.2" - node-releases "^1.1.61" - -browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.16.6, browserslist@^4.16.7, browserslist@^4.17.3, browserslist@^4.17.5, browserslist@^4.19.1, browserslist@^4.20.2, browserslist@^4.21.0, browserslist@^4.21.3: +browserslist@4.14.2, browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.16.5, browserslist@^4.16.6, browserslist@^4.16.7, browserslist@^4.17.3, browserslist@^4.17.5, browserslist@^4.19.1, browserslist@^4.20.2, browserslist@^4.21.0, browserslist@^4.21.3: version "4.21.5" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.5.tgz#75c5dae60063ee641f977e00edd3cfb2fb7af6a7" integrity sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w== @@ -10268,14 +10305,6 @@ buffer@^4.3.0: ieee754 "^1.1.4" isarray "^1.0.0" -buffer@^5.5.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" @@ -10293,6 +10322,16 @@ builtins@^5.0.0: dependencies: semver "^7.0.0" +byline@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/byline/-/byline-5.0.0.tgz#741c5216468eadc457b03410118ad77de8c1ddb1" + integrity sha512-s6webAy+R4SR8XVuJWt2V2rGvhnrhxN+9S15GNuTK3wKPOXFF6RNc+8ug2XhH+2s4f+uudG4kUVYmYOQWL2g0Q== + +byte-size@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/byte-size/-/byte-size-5.0.1.tgz#4b651039a5ecd96767e71a3d7ed380e48bed4191" + integrity sha512-/XuKeqWocKsYa/cBY1YbSJSWWqTi4cFgr9S6OyM7PBaPbr9zvNGwWP33vt0uqGhwDdN+y3yhbXVILEUpnwEWGw== + bytes@1: version "1.0.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-1.0.0.tgz#3569ede8ba34315fab99c3e92cb04c7220de1fa8" @@ -10308,7 +10347,7 @@ bytes@3.1.2: resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== -cacache@^12.0.2: +cacache@^12.0.0, cacache@^12.0.2, cacache@^12.0.4: version "12.0.4" resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.4.tgz#668bcbd105aeb5f1d92fe25570ec9525c8faa40c" integrity sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ== @@ -10396,19 +10435,6 @@ cacheable-lookup@^5.0.3: resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz#5a6b865b2c44357be3d5ebc2a467b032719a7005" integrity sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA== -cacheable-request@^6.0.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912" - integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg== - dependencies: - clone-response "^1.0.2" - get-stream "^5.1.0" - http-cache-semantics "^4.0.0" - keyv "^3.0.0" - lowercase-keys "^2.0.0" - normalize-url "^4.1.0" - responselike "^1.0.2" - cacheable-request@^7.0.2: version "7.0.2" resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.2.tgz#ea0d0b889364a25854757301ca12b2da77f91d27" @@ -10442,6 +10468,11 @@ call-bind@^1.0.0, call-bind@^1.0.2: function-bind "^1.1.1" get-intrinsic "^1.0.2" +call-limit@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/call-limit/-/call-limit-1.1.1.tgz#ef15f2670db3f1992557e2d965abc459e6e358d4" + integrity sha512-5twvci5b9eRBw2wCfPtN0GmlR2/gadZqyFpPhOK6CvMFoFgA+USnZ6Jpu1lhG9h85pQ3Ouil3PfXWRD4EUaRiQ== + call-me-maybe@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" @@ -10487,6 +10518,11 @@ camelcase@^2.0.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8= +camelcase@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" + integrity sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw== + camelcase@^5.3.1: version "5.3.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" @@ -10514,15 +10550,10 @@ caniuse-api@^3.0.0: lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001449: - version "1.0.30001466" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001466.tgz#c1e6197c540392e09709ecaa9e3e403428c53375" - integrity sha512-ewtFBSfWjEmxUgNBSZItFSmVtvk9zkwkl1OfRZlKA8slltRN+/C/tuGVrF9styXkN36Yu3+SeJ1qkXxDEyNZ5w== - -caniuse-lite@^1.0.30001125: - version "1.0.30001472" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001472.tgz#3f484885f2a2986c019dc416e65d9d62798cdd64" - integrity sha512-xWC/0+hHHQgj3/vrKYY0AAzeIUgr7L9wlELIcAvZdDUHlhL/kNxMdnQLOSOQfP8R51ZzPhmHdyMkI0MMpmxCfg== +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001157, caniuse-lite@^1.0.30001449: + version "1.0.30001473" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001473.tgz#3859898b3cab65fc8905bb923df36ad35058153c" + integrity sha512-ewDad7+D2vlyy+E4UJuVfiBsU69IL+8oVmTuZnH5Q6CIUbxNfI50uVpRHbUPDD6SUaN2o0Lh4DhTrvLG/Tn1yg== capture-exit@^2.0.0: version "2.0.0" @@ -10689,7 +10720,7 @@ chokidar@^2.1.8: optionalDependencies: fsevents "^1.2.7" -chownr@^1.1.1: +chownr@^1.1.1, chownr@^1.1.2, chownr@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== @@ -10709,6 +10740,11 @@ chromium-pickle-js@^0.2.0: resolved "https://registry.yarnpkg.com/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz#04a106672c18b085ab774d983dfa3ea138f22205" integrity sha1-BKEGZywYsIWrd02YPfo+oTjyIgU= +ci-info@^1.5.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" + integrity sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A== + ci-info@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" @@ -10724,6 +10760,13 @@ ci-info@^3.3.2: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.3.2.tgz#6d2967ffa407466481c6c90b6e16b3098f080128" integrity sha512-xmDt/QIAdeZ9+nfdPsaBCpMvHNLFiLdjj59qjqn+6iPe6YmHGQ35sBnQ8uslRBXFmXkiZQOJRjvQeoGppoTjjg== +cidr-regex@^2.0.10: + version "2.0.10" + resolved "https://registry.yarnpkg.com/cidr-regex/-/cidr-regex-2.0.10.tgz#af13878bd4ad704de77d6dc800799358b3afa70d" + integrity sha512-sB3ogMQXWvreNPbJUZMRApxuRYd+KoIo4RGQ81VatjmMW6WJPo+IJZ2846FGItr9VzKo5w7DXzijPLGtSd0N3Q== + dependencies: + ip-regex "^2.1.0" + 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" @@ -10771,15 +10814,7 @@ clean-css-promise@^0.1.0: clean-css "^3.4.5" pinkie-promise "^2.0.0" -clean-css@^3.4.5: - version "3.4.28" - resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-3.4.28.tgz#bf1945e82fc808f55695e6ddeaec01400efd03ff" - integrity sha512-aTWyttSdI2mYi07kWqHi24NUU9YlELFKGOAgFzZjDN1064DMAOy2FBuoyGmkKRlXkbpXd0EVHmiVkbKhKoirTw== - dependencies: - commander "2.8.x" - source-map "0.4.x" - -clean-css@^4.2.3: +clean-css@^3.4.5, clean-css@^4.1.11, clean-css@^4.2.3: version "4.2.4" resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.4.tgz#733bf46eba4e607c6891ea57c24a989356831178" integrity sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A== @@ -10796,11 +10831,24 @@ clean-up-path@^1.0.0: resolved "https://registry.yarnpkg.com/clean-up-path/-/clean-up-path-1.0.0.tgz#de9e8196519912e749c9eaf67c13d64fac72a3e5" integrity sha512-PHGlEF0Z6976qQyN6gM7kKH6EH0RdfZcc8V+QhFe36eRxV0SMH5OUBZG7Bxa9YcreNzyNbK63cGiZxdSZgosRw== +cli-boxes@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" + integrity sha512-3Fo5wu8Ytle8q9iCzS4D2MWVL2X7JVWRiS1BnXbTFDhS9c/REkM9vd1AmabsoZoY5/dGi5TT9iKL8Kb6DeBRQg== + cli-boxes@^2.2.0, cli-boxes@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== +cli-columns@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/cli-columns/-/cli-columns-3.1.2.tgz#6732d972979efc2ae444a1f08e08fa139c96a18e" + integrity sha512-iQYpDgpPPmCjn534ikQOhi+ydP6uMar+DtJ6a0In4aGL/PKqWfao75s6eF81quQQaz7isGz+goNECLARRZswdg== + dependencies: + string-width "^2.0.0" + strip-ansi "^3.0.1" + cli-cursor@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" @@ -10838,6 +10886,16 @@ cli-table3@0.6.0, cli-table3@^0.6.0: optionalDependencies: colors "^1.1.2" +cli-table3@^0.5.0, cli-table3@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.5.1.tgz#0252372d94dfc40dbd8df06005f48f31f656f202" + integrity sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw== + dependencies: + object-assign "^4.1.0" + string-width "^2.1.1" + optionalDependencies: + colors "^1.1.2" + cli-table3@^0.6.1: version "0.6.3" resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.3.tgz#61ab765aac156b52f222954ffc607a6f01dbeeb2" @@ -10898,6 +10956,15 @@ clipboard@^2.0.8: select "^1.1.2" tiny-emitter "^2.0.0" +cliui@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" + integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== + dependencies: + string-width "^3.1.0" + strip-ansi "^5.2.0" + wrap-ansi "^5.1.0" + cliui@^7.0.2: version "7.0.4" resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" @@ -10933,6 +11000,14 @@ clone@^2.1.2: resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18= +cmd-shim@^3.0.0, cmd-shim@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/cmd-shim/-/cmd-shim-3.0.3.tgz#2c35238d3df37d98ecdd7d5f6b8dc6b21cadc7cb" + integrity sha512-DtGg+0xiFhQIntSBRzL2fRQBnmtAVwXIDo4Qq46HPpObYquxMaZS4sb82U9nH91qJrlosC1wa9gwr0QyL/HypA== + dependencies: + graceful-fs "^4.1.2" + mkdirp "~0.5.0" + co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" @@ -11029,6 +11104,14 @@ colors@^1.1.2, colors@^1.4.0: resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== +columnify@~1.5.4: + version "1.5.4" + resolved "https://registry.yarnpkg.com/columnify/-/columnify-1.5.4.tgz#4737ddf1c7b69a8a7c340570782e947eec8e78bb" + integrity sha512-rFl+iXVT1nhLQPfGDw+3WcS8rmm7XsLKUmhsGE3ihzzpIikeGrTaZPIRKYWeLsLBypsHzjXIvYEltVUZS84XxQ== + dependencies: + strip-ansi "^3.0.0" + wcwidth "^1.0.0" + combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" @@ -11036,25 +11119,11 @@ combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" -combined-stream@~0.0.4: - version "0.0.7" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-0.0.7.tgz#0137e657baa5a7541c57ac37ac5fc07d73b4dc1f" - integrity sha512-qfexlmLp9MyrkajQVyjEDb0Vj+KhRgR/rxLiVhaihlT+ZkX0lReqtH6Ack40CvMDERR4b5eFp3CreskpBs1Pig== - dependencies: - delayed-stream "0.0.5" - comma-separated-tokens@^1.0.0: version "1.0.8" resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz#632b80b6117867a158f1080ad498b2fbe7e3f5ea" integrity sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw== -commander@2.8.x: - version "2.8.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.8.1.tgz#06be367febfda0c330aa1e2a072d3dc9762425d4" - integrity sha512-+pJLBFVk+9ZZdlAOB5WuIElVPPth47hILFkmGym57aq8kwxsowvByvB0DHs1vQAhyMZzdcpTtF0VDKGkSDR4ZQ== - dependencies: - graceful-readlink ">= 1.0.0" - commander@2.9.0: version "2.9.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" @@ -11177,7 +11246,7 @@ concat-stream@^1.5.0, concat-stream@^1.6.2: readable-stream "^2.2.2" typedarray "^0.0.6" -config-chain@^1.1.11: +config-chain@^1.1.11, config-chain@^1.1.13: version "1.1.13" resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.13.tgz#fad0795aa6a6cdaff9ed1b68e9dff94372c232f4" integrity sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ== @@ -11185,6 +11254,18 @@ config-chain@^1.1.11: ini "^1.3.4" proto-list "~1.2.1" +configstore@^3.0.0: + version "3.1.5" + resolved "https://registry.yarnpkg.com/configstore/-/configstore-3.1.5.tgz#e9af331fadc14dabd544d3e7e76dc446a09a530f" + integrity sha512-nlOhI4+fdzoK5xmJ+NY+1gZK56bwEaWZr8fYuXohZ9Vkc1o3a4T/R3M+yE/w7x/ZVJ1zF8c+oaOvF0dztdUgmA== + dependencies: + dot-prop "^4.2.1" + graceful-fs "^4.1.2" + make-dir "^1.0.0" + unique-string "^1.0.0" + write-file-atomic "^2.0.0" + xdg-basedir "^3.0.0" + configstore@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/configstore/-/configstore-5.0.1.tgz#d365021b5df4b98cdd187d6a3b0e3f6a7cc5ed96" @@ -11507,6 +11588,15 @@ cross-spawn@7.0.3, cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.2, c shebang-command "^2.0.0" which "^2.0.1" +cross-spawn@^5.0.1: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + integrity sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A== + dependencies: + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + cross-spawn@^6.0.0, cross-spawn@^6.0.5: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" @@ -11518,12 +11608,12 @@ cross-spawn@^6.0.0, cross-spawn@^6.0.5: shebang-command "^1.2.0" which "^1.2.9" -cryptiles@0.2.x: - version "0.2.2" - resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-0.2.2.tgz#ed91ff1f17ad13d3748288594f8a48a0d26f325c" - integrity sha512-gvWSbgqP+569DdslUiCelxIv3IYK5Lgmq1UrRnk+s1WxQOQ16j3GPDcjdtgL5Au65DU/xQi6q3xPtf5Kta+3IQ== +cryptiles@~4.1.2: + version "4.1.3" + resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-4.1.3.tgz#2461d3390ea0b82c643a6ba79f0ed491b0934c25" + integrity sha512-gT9nyTMSUC1JnziQpPbxKGBbUg8VL7Zn2NB4E1cJYvuXdElHrwxrV9bmltZGDzet45zSDGyYceueke1TjynGzw== dependencies: - boom "0.4.x" + boom "7.x.x" crypto-browserify@^3.11.0: version "3.12.0" @@ -11542,6 +11632,11 @@ crypto-browserify@^3.11.0: randombytes "^2.0.0" randomfill "^1.0.3" +crypto-random-string@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" + integrity sha512-GsVpkFPlycH7/fRR7Dhcmnoii54gV1nz7y4CWyeFS14N+JVBBhY+r8amRHE4BwSYal7BPTDp8isvAlCxyFt3Hg== + crypto-random-string@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" @@ -11642,12 +11737,7 @@ css-url-regex@^1.1.0: resolved "https://registry.yarnpkg.com/css-url-regex/-/css-url-regex-1.1.0.tgz#83834230cc9f74c457de59eebd1543feeb83b7ec" integrity sha1-g4NCMMyfdMRX3lnuvRVD/uuDt+w= -css-what@^3.2.1: - version "3.4.2" - resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.4.2.tgz#ea7026fcb01777edbde52124e21f327e7ae950e4" - integrity sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ== - -css-what@^5.0.0, css-what@^5.0.1: +css-what@^3.2.1, css-what@^5.0.0, css-what@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/css-what/-/css-what-5.0.1.tgz#3efa820131f4669a8ac2408f9c32e7c7de9f4cad" integrity sha512-FYDTSHb/7KXsWICVsxdmiExPjCfRC4qRFBdVwv7Ax9hMnvMmEjP9RfxTEZ3qPZGmADDn2vAKSo9UcN1jKVYscg== @@ -11696,11 +11786,6 @@ csstype@^3.1.0: resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.1.tgz#841b532c45c758ee546a11d5bd7b7b473c8c30b9" integrity sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw== -ctype@0.5.3: - version "0.5.3" - resolved "https://registry.yarnpkg.com/ctype/-/ctype-0.5.3.tgz#82c18c2461f74114ef16c135224ad0b9144ca12f" - integrity sha512-T6CEkoSV4q50zW3TlTHMbzy1E5+zlnNcY+yb7tWVYlTwPhx9LpnfAkd4wecpWknDyptp4k97LUZeInlf6jdzBg== - currently-unhandled@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" @@ -11799,6 +11884,13 @@ debug@2.6.9, debug@^2.1.0, debug@^2.1.1, debug@^2.1.3, debug@^2.2.0, debug@^2.3. dependencies: ms "2.0.0" +debug@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== + dependencies: + ms "2.0.0" + debug@4, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" @@ -11813,7 +11905,7 @@ debug@^3.0.0, debug@^3.0.1, debug@^3.1.0, debug@^3.1.1, debug@^3.2.7: dependencies: ms "^2.1.1" -debuglog@^1.0.1: +debuglog@*, debuglog@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" integrity sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI= @@ -11841,13 +11933,6 @@ decode-uri-component@^0.2.0: resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9" integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ== -decompress-response@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" - integrity sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA== - dependencies: - mimic-response "^1.0.0" - decompress-response@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" @@ -11887,11 +11972,6 @@ defaults@^1.0.3: dependencies: clone "^1.0.2" -defer-to-connect@^1.0.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" - integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== - defer-to-connect@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587" @@ -11931,11 +12011,6 @@ define-property@^2.0.2: is-descriptor "^1.0.2" isobject "^3.0.1" -delayed-stream@0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-0.0.5.tgz#d4b1f43a93e8296dfe02694f4680bc37a313c73f" - integrity sha512-v+7uBd1pqe5YtgPacIIbZ8HuHeLFVNe4mUEyFDXL6KiqzEykjbw+5mXZXpGFgNVasdL4jWKgaKIXrEHiynN1LA== - delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -12003,6 +12078,11 @@ detect-indent@^6.0.0: resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-6.1.0.tgz#592485ebbbf6b3b1ab2be175c8393d04ca0d57e6" integrity sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA== +detect-indent@~5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d" + integrity sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g== + detect-libc@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" @@ -12013,6 +12093,11 @@ detect-newline@3.1.0, detect-newline@^3.0.0: resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== +detect-newline@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2" + integrity sha512-CwffZFvlJffUg9zZA0uqrjQayUTC8ob94pnr5sFwaVv3IOmkfUHcWH+jXaQK3askE51Cqe8/9Ql/0uXNwqZ8Zg== + detect-node@^2.0.4: version "2.1.0" resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" @@ -12042,6 +12127,14 @@ dezalgo@^1.0.0: asap "^2.0.0" wrappy "1" +dezalgo@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/dezalgo/-/dezalgo-1.0.4.tgz#751235260469084c132157dfa857f386d4c33d81" + integrity sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig== + dependencies: + asap "^2.0.0" + wrappy "1" + dialog-polyfill@^0.5.6: version "0.5.6" resolved "https://registry.yarnpkg.com/dialog-polyfill/-/dialog-polyfill-0.5.6.tgz#7507b4c745a82fcee0fa07ce64d835979719599a" @@ -12213,6 +12306,13 @@ dot-case@^3.0.4: no-case "^3.0.4" tslib "^2.0.3" +dot-prop@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.1.tgz#45884194a71fc2cda71cbb4bceb3a4dd2f433ba4" + integrity sha512-l0p4+mIuJIua0mhxGoh4a+iNL9bmeK5DvnSVQa6T0OhrVmaEa1XScX5Etc673FePCJOArq/4Pa2cLGODUWTPOQ== + dependencies: + is-obj "^1.0.0" + dot-prop@^5.2.0: version "5.3.0" resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88" @@ -12239,6 +12339,11 @@ dotenv-webpack@^1.8.0: dependencies: dotenv-defaults "^1.0.2" +dotenv@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-5.0.1.tgz#a5317459bd3d79ab88cff6e44057a6a3fbb1fcef" + integrity sha512-4As8uPrjfwb7VXC+WnLCbXK7y+Ueb2B3zgNCePYfhxS1PYeaO1YTeplffTEcbfLhvFNGLAz90VvJs9yomG7bow== + dotenv@^6.2.0: version "6.2.0" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-6.2.0.tgz#941c0410535d942c8becf28d3f357dbd9d476064" @@ -12260,11 +12365,6 @@ downshift@^6.0.15: react-is "^17.0.2" tslib "^2.3.0" -duplexer3@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.5.tgz#0b5e4d7bad5de8901ea4440624c8e1d20099217e" - integrity sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA== - duplexer@^0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" @@ -12306,6 +12406,11 @@ editions@^2.2.0: errlop "^2.0.0" semver "^6.3.0" +editor@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/editor/-/editor-1.0.0.tgz#60c7f87bd62bcc6a894fa8ccd6afb7823a24f742" + integrity sha512-SoRmbGStwNYHgKfjOrX2L0mUvp9bUVv0uPppZSOMAntEbcFtoC3MKF5b3T6HQPXKIV+QGY3xPO3JK5it5lVkuw== + ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" @@ -12376,11 +12481,6 @@ electron-rebuild@^3.2.6: tar "^6.0.5" yargs "^17.0.1" -electron-to-chromium@^1.3.564: - version "1.4.343" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.343.tgz#90f85c4c67aec42b3d076e597911b7b6a2d026fd" - integrity sha512-22C6pOljO+QQ/yeBZJkxewjsGwSKCXymng7dF8lir3m8iJGi6guoLVkK8jghCf3o0/tARFASAgLP8OzR9SKRCA== - electron-to-chromium@^1.4.284: version "1.4.305" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.305.tgz#e4dfe3e06ab783f33171f9bde9e8ed092510fcd0" @@ -12393,7 +12493,7 @@ element-resize-detector@^1.2.2: dependencies: batch-processor "1.0.0" -elliptic@^6.5.3: +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== @@ -13925,14 +14025,14 @@ ember-template-lint@^4.14.0: v8-compile-cache "^2.3.0" yargs "^17.5.1" -ember-template-recast@^6.1.3: - version "6.1.3" - resolved "https://registry.yarnpkg.com/ember-template-recast/-/ember-template-recast-6.1.3.tgz#1e9b256ee9da24bcaa7c213088d01f32afc88001" - integrity sha512-45lkfjrWlrMPlOd5rLFeQeePZwAvcS//x1x15kaiQTlqQdYWiYNXwbpWHqV+p9fXY6bEjl6EbyPhG/zBkgh8MA== +ember-template-recast@^6.0.0, ember-template-recast@^6.1.3: + version "6.1.4" + resolved "https://registry.yarnpkg.com/ember-template-recast/-/ember-template-recast-6.1.4.tgz#e964c184adfd876878009f8aa0b84c95633fce20" + integrity sha512-fCh+rOK6z+/tsdkTbOE+e7f84P6ObnIRQrCCrnu21E4X05hPeradikIkRMhJdxn4NWrxitfZskQDd37TR/lsNQ== dependencies: - "@glimmer/reference" "^0.83.1" - "@glimmer/syntax" "^0.83.1" - "@glimmer/validator" "^0.83.0" + "@glimmer/reference" "^0.84.3" + "@glimmer/syntax" "^0.84.3" + "@glimmer/validator" "^0.84.3" async-promise-queue "^1.0.5" colors "^1.4.0" commander "^8.3.0" @@ -13940,7 +14040,7 @@ ember-template-recast@^6.1.3: ora "^5.4.0" slash "^3.0.0" tmp "^0.2.1" - workerpool "^6.1.5" + workerpool "^6.4.0" ember-truth-helpers@^3.0.0: version "3.0.0" @@ -14022,7 +14122,7 @@ encodeurl@^1.0.2, encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== -encoding@^0.1.12: +encoding@^0.1.11, encoding@^0.1.12: version "0.1.13" resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== @@ -14099,16 +14199,11 @@ entities@^2.0.0: resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== -entities@^3.0.1, entities@~3.0.1: +entities@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/entities/-/entities-3.0.1.tgz#2b887ca62585e96db3903482d336c1006c3001d4" integrity sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q== -entities@~1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" - integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== - entities@~2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/entities/-/entities-2.1.0.tgz#992d3129cf7df6870b96c57858c249a120f8b8b5" @@ -14124,6 +14219,11 @@ envinfo@^7.7.3: resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475" integrity sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw== +err-code@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/err-code/-/err-code-1.1.2.tgz#06e0116d3028f6aef4806849eb0ea6a748ae6960" + integrity sha512-CJAN+O0/yA1CKfRn9SXOGctSpEM7DCon/r/5r2eXFMY2zCCJBasFhcM5I+1kh3Ap11FsQCX+vGHceNPvpWKhoA== + err-code@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9" @@ -14285,6 +14385,18 @@ es6-map@^0.1.3: es6-symbol "~3.1.1" event-emitter "~0.3.5" +es6-promise@^4.0.3: + version "4.2.8" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" + integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== + +es6-promisify@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" + integrity sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ== + dependencies: + es6-promise "^4.0.3" + es6-set@~0.1.5: version "0.1.5" resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1" @@ -14327,7 +14439,7 @@ es6-weak-map@^2.0.1: es6-iterator "^2.0.3" es6-symbol "^3.1.1" -escalade@^3.0.2, escalade@^3.1.1: +escalade@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== @@ -14679,6 +14791,19 @@ exec-sh@^0.3.2, exec-sh@^0.3.4: resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.6.tgz#ff264f9e325519a60cb5e273692943483cca63bc" integrity sha512-nQn+hI3yp+oD0huYhKwvYI32+JFeq+XkNcD1GAo3Y/MjxsfVGmrrzrnzjWiNY6f+pUCP440fThsFh5gZrRAU/w== +execa@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" + integrity sha512-RztN09XglpYI7aBBrJCPW95jEH7YF1UEPOoX9yDhUTPdp7mK+CQvnLTuD10BNXZ3byLTu2uehZ8EcKT/4CGiFw== + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + execa@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" @@ -15088,7 +15213,7 @@ fd-slicer@~1.1.0: dependencies: pend "~1.2.0" -figgy-pudding@^3.5.1: +figgy-pudding@^3.4.1, figgy-pudding@^3.5.1, figgy-pudding@^3.5.2: version "3.5.2" resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e" integrity sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw== @@ -15192,6 +15317,11 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" +filter-obj@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/filter-obj/-/filter-obj-1.1.0.tgz#9b311112bc6c6127a16e016c6c5d7f19e0805c5b" + integrity sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ== + finalhandler@1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" @@ -15257,6 +15387,11 @@ find-node-modules@^2.1.2: findup-sync "^4.0.0" merge "^2.1.0" +find-npm-prefix@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/find-npm-prefix/-/find-npm-prefix-1.0.2.tgz#8d8ce2c78b3b4b9e66c8acc6a37c231eb841cfdf" + integrity sha512-KEftzJ+H90x6pcKtdXZEPsQse8/y/UnvzRKrOSQFprnrGaFuJ62fVkP34Iu2IYuMvyauCyoLTNkJZgrrGA2wkA== + find-root@1.1.0, find-root@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4" @@ -15425,7 +15560,7 @@ focus-trap@^6.7.1: dependencies: tabbable "^5.3.3" -follow-redirects@^1.0.0: +follow-redirects@^1.0.0, follow-redirects@^1.14.8: version "1.15.2" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== @@ -15440,11 +15575,6 @@ foreach@^2.0.4: resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.6.tgz#87bcc8a1a0e74000ff2bf9802110708cfb02eb6e" integrity sha512-k6GAGDyqLe9JaebCsFCoudPPWfihKu8pylYXRlqP1J7ms39iPoTtk2fviNglIeQEwdh0bQeKJ01ZPyuyQvKzwg== -forever-agent@~0.5.0: - version "0.5.2" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.5.2.tgz#6d0e09c4921f94a27f63d3b49c5feff1ea4c5130" - integrity sha512-PDG5Ef0Dob/JsZUxUltJOhm/Y9mlteAE+46y3M9RBz/Rd3QVENJ75aGRhN56yekTUboaBIkd8KVWX2NjF6+91A== - forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" @@ -15491,15 +15621,6 @@ form-data@^3.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" -form-data@~0.1.0: - version "0.1.4" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-0.1.4.tgz#91abd788aba9702b1aabfa8bc01031a2ac9e3b12" - integrity sha512-x8eE+nzFtAMA0YYlSxf/Qhq6vP1f8wSoZ7Aw1GuctBcmudCNuTUmmx45TfEplyb6cjsZO/jvh6+1VpZn24ez+w== - dependencies: - async "~0.9.0" - combined-stream "~0.0.4" - mime "~1.2.11" - form-data@~2.3.2: version "2.3.3" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" @@ -15531,6 +15652,14 @@ fresh@0.5.2: resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== +from2@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/from2/-/from2-1.3.0.tgz#88413baaa5f9a597cfde9221d86986cd3c061dfd" + integrity sha512-1eKYoECvhpM4IT70THQV8XNfmZoIlnROymbwOSazfmQO3kK+zCV+LSqUDzl7gDo3MZddCFeVa9Zg3Hi6FXqcgg== + dependencies: + inherits "~2.0.1" + readable-stream "~1.1.10" + from2@^2.1.0: version "2.3.0" resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" @@ -15688,7 +15817,16 @@ fs-updater@^1.0.4: heimdalljs-logger "^0.1.9" rimraf "^2.6.2" -fs-write-stream-atomic@^1.0.8: +fs-vacuum@^1.2.10, fs-vacuum@~1.2.10: + version "1.2.10" + resolved "https://registry.yarnpkg.com/fs-vacuum/-/fs-vacuum-1.2.10.tgz#b7629bec07a4031a2548fdf99f5ecf1cc8b31e36" + integrity sha512-bwbv1FcWYwxN1F08I1THN8nS4Qe/pGq0gM8dy1J34vpxxp3qgZKJPPaqex36RyZO0sD2J+2ocnbwC2d/OjYICQ== + dependencies: + graceful-fs "^4.1.2" + path-is-inside "^1.0.1" + rimraf "^2.5.2" + +fs-write-stream-atomic@^1.0.8, fs-write-stream-atomic@~1.0.10: version "1.0.10" resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" integrity sha1-tH31NJPvkR33VzHnCp3tAYnbQMk= @@ -15803,12 +15941,34 @@ gauge@~2.7.3: strip-ansi "^3.0.1" wide-align "^1.1.0" +genfun@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/genfun/-/genfun-5.0.0.tgz#9dd9710a06900a5c4a5bf57aca5da4e52fe76537" + integrity sha512-KGDOARWVga7+rnB3z9Sd2Letx515owfk0hSxHGuqjANb1M+x2bGZGqHLiozPsYMdM2OubeMni/Hpwmjq6qIUhA== + gensync@^1.0.0-beta.1, gensync@^1.0.0-beta.2: version "1.0.0-beta.2" resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== -get-caller-file@^2.0.5: +gentle-fs@^2.3.0, gentle-fs@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/gentle-fs/-/gentle-fs-2.3.1.tgz#11201bf66c18f930ddca72cf69460bdfa05727b1" + integrity sha512-OlwBBwqCFPcjm33rF2BjW+Pr6/ll2741l+xooiwTCeaX2CA1ZuclavyMBe0/KlR21/XGsgY6hzEQZ15BdNa13Q== + dependencies: + aproba "^1.1.2" + chownr "^1.1.2" + cmd-shim "^3.0.3" + fs-vacuum "^1.2.10" + graceful-fs "^4.1.11" + iferr "^0.1.5" + infer-owner "^1.0.4" + mkdirp "^0.5.1" + path-is-inside "^1.0.2" + read-cmd-shim "^1.0.1" + slide "^1.1.6" + +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== @@ -15868,6 +16028,11 @@ get-stdin@^9.0.0: resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-9.0.0.tgz#3983ff82e03d56f1b2ea0d3e60325f39d703a575" integrity sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA== +get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + integrity sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ== + get-stream@^4.0.0, get-stream@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" @@ -15937,35 +16102,13 @@ glob-base@^0.3.0: glob-parent "^2.0.0" is-glob "^2.0.0" -glob-parent@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" - integrity sha512-JDYOvfxio/t42HKdxkAYaCiBN7oYiuxykOxKxdaUW5Qn0zaYN3gRQWolrwdnf0shM9/EP0ebuuTmyoXNr1cC5w== - dependencies: - is-glob "^2.0.0" - -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@^2.0.0, glob-parent@^3.1.0, glob-parent@^5.1.2, glob-parent@^6.0.1, 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-parent@^6.0.1: - version "6.0.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" - integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== - dependencies: - is-glob "^4.0.3" - glob-promise@^3.4.0: version "3.4.0" resolved "https://registry.yarnpkg.com/glob-promise/-/glob-promise-3.4.0.tgz#b6b8f084504216f702dc2ce8c9bc9ac8866fdb20" @@ -16030,6 +16173,18 @@ glob@^7.2.0: once "^1.3.0" path-is-absolute "^1.0.0" +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-agent@^2.0.2: version "2.2.0" resolved "https://registry.yarnpkg.com/global-agent/-/global-agent-2.2.0.tgz#566331b0646e6bf79429a16877685c4a1fbf76dc" @@ -16043,7 +16198,7 @@ global-agent@^2.0.2: semver "^7.3.2" serialize-error "^7.0.1" -global-dirs@^0.1.1: +global-dirs@^0.1.0, global-dirs@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445" integrity sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg== @@ -16239,7 +16394,7 @@ good-listener@^1.2.2: dependencies: delegate "^3.1.2" -got@^11.7.0, got@^11.8.2: +got@^11.7.0, got@^11.8.2, got@^11.8.5, got@^6.7.1, got@^9.6.0: version "11.8.6" resolved "https://registry.yarnpkg.com/got/-/got-11.8.6.tgz#276e827ead8772eddbcfc97170590b841823233a" integrity sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g== @@ -16256,28 +16411,16 @@ got@^11.7.0, got@^11.8.2: p-cancelable "^2.0.0" responselike "^2.0.0" -got@^9.6.0: - version "9.6.0" - resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" - integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q== - dependencies: - "@sindresorhus/is" "^0.14.0" - "@szmarczak/http-timer" "^1.1.2" - cacheable-request "^6.0.0" - decompress-response "^3.3.0" - duplexer3 "^0.1.4" - get-stream "^4.1.0" - lowercase-keys "^1.0.1" - mimic-response "^1.0.1" - p-cancelable "^1.0.0" - to-readable-stream "^1.0.0" - url-parse-lax "^3.0.0" - graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.4: version "4.2.8" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a" integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg== +graceful-fs@^4.2.10, graceful-fs@^4.2.2: + 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== + graceful-fs@^4.2.6, graceful-fs@^4.2.9: version "4.2.10" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" @@ -16394,7 +16537,7 @@ has-tostringtag@^1.0.0: dependencies: has-symbols "^1.0.2" -has-unicode@^2.0.0, has-unicode@^2.0.1: +has-unicode@^2.0.0, has-unicode@^2.0.1, has-unicode@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ== @@ -16539,15 +16682,15 @@ hastscript@^6.0.0: property-information "^5.0.0" space-separated-tokens "^1.0.0" -hawk@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/hawk/-/hawk-1.1.1.tgz#87cd491f9b46e4e2aeaca335416766885d2d1ed9" - integrity sha512-am8sVA2bCJIw8fuuVcKvmmNnGFUGW8spTkVtj2fXTEZVkfN42bwFZFtDem57eFi+NSxurJB8EQ7Jd3uCHLn8Vw== +hawk@^9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/hawk/-/hawk-9.0.1.tgz#0be51769103e76fe97a97ae7fa356c313bb93160" + integrity sha512-H2E+5ATFEXmorgVzYl3NzG3PCo2e+euYrHDnRpLLdOtJrQHGRXrJT9/joWnrkHCtzDZkaNoLXg/+TsSkD06eNg== dependencies: - boom "0.4.x" - cryptiles "0.2.x" - hoek "0.9.x" - sntp "0.2.x" + "@hapi/b64" "5.x.x" + "@hapi/boom" "9.x.x" + "@hapi/cryptiles" "5.x.x" + "@hapi/hoek" "9.x.x" he@^1.2.0: version "1.2.0" @@ -16599,10 +16742,10 @@ hmac-drbg@^1.0.1: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.1" -hoek@0.9.x: - version "0.9.1" - resolved "https://registry.yarnpkg.com/hoek/-/hoek-0.9.1.tgz#3d322462badf07716ea7eb85baf88079cddce505" - integrity sha512-ZZ6eGyzGjyMTmpSPYVECXy9uNfqBR7x5CavhUaLOeD6W0vWK1mp/b7O3f86XE0Mtfo9rZ6Bh3fnuw9Xr8MF9zA== +hoek@6.x.x, hoek@~4.2.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.1.tgz#9634502aa12c445dd5a7c5734b572bb8738aacbb" + integrity sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA== hoist-non-react-statics@^3.3.0: version "3.3.2" @@ -16626,25 +16769,13 @@ homedir-polyfill@^1.0.1: dependencies: parse-passwd "^1.0.0" -hosted-git-info@^2.1.4: - version "2.8.9" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" - integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== - -hosted-git-info@^4.0.1: - version "4.1.0" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-4.1.0.tgz#827b82867e9ff1c8d0c4d9d53880397d2c86d224" - integrity sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA== +hosted-git-info@^2.1.4, hosted-git-info@^2.7.1, hosted-git-info@^2.8.9, hosted-git-info@^3.0.8, hosted-git-info@^4.0.1, hosted-git-info@^5.0.0: + version "3.0.8" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-3.0.8.tgz#6e35d4cc87af2c5f816e4cb9ce350ba87a3f370d" + integrity sha512-aXpmwoOhRBrw6X3j0h5RloK4x1OzsxMPyxqIHyNfSe2pypkVTZFpEiRoSipPEPlMrh0HW/XsjkJ5WgnCirpNUw== dependencies: lru-cache "^6.0.0" -hosted-git-info@^5.0.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-5.2.1.tgz#0ba1c97178ef91f3ab30842ae63d6a272341156f" - integrity sha512-xIcQYMnhcx2Nr4JTjsFmwwnr9vldugPy9uVm0o87bjqqWMv9GaqsTeT+i99wTl0mk1uLxJtHxLb8kymqTENQsw== - dependencies: - lru-cache "^7.5.1" - html-encoding-sniffer@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3" @@ -16725,6 +16856,11 @@ htmlparser2@^7.2.0: domutils "^2.8.0" entities "^3.0.1" +http-cache-semantics@^3.8.1: + version "3.8.1" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2" + integrity sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w== + http-cache-semantics@^4.0.0, http-cache-semantics@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" @@ -16756,6 +16892,14 @@ http-parser-js@>=0.5.1: resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.3.tgz#01d2709c79d41698bb01d4decc5e9da4e4a033d9" integrity sha512-t7hjvef/5HEK7RWTdUzVUhl8zkEu+LlaE0IYzdMuvbSDipxBRpOn4Uhw8ZyECEa808iVT8XCjzo6xmYt4CiLZg== +http-proxy-agent@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405" + integrity sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg== + dependencies: + agent-base "4" + debug "3.1.0" + http-proxy-agent@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" @@ -16774,15 +16918,6 @@ http-proxy@^1.13.1, http-proxy@^1.18.1: follow-redirects "^1.0.0" requires-port "^1.0.0" -http-signature@~0.10.0: - version "0.10.1" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-0.10.1.tgz#4fbdac132559aa8323121e540779c0a012b27e66" - integrity sha512-coK8uR5rq2IMj+Hen+sKPA5ldgbCc1/spPdKCL1Fw6h+D0s/2LzMcRK0Cqufs1h0ryx/niwBHGFu8HC3hwU+lA== - dependencies: - asn1 "0.1.11" - assert-plus "^0.1.5" - ctype "0.5.3" - http-signature@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" @@ -16805,6 +16940,14 @@ https-browserify@^1.0.0: resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= +https-proxy-agent@^2.2.3: + version "2.2.4" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz#4ee7a737abd92678a293d9b34a1af4d0d08c787b" + integrity sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg== + dependencies: + agent-base "^4.3.0" + debug "^3.1.0" + https-proxy-agent@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz#702b71fb5520a132a66de1f67541d9e62154d82b" @@ -16891,7 +17034,7 @@ icss-utils@^5.0.0, icss-utils@^5.1.0: resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== -ieee754@^1.1.13, ieee754@^1.1.4: +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== @@ -16901,6 +17044,18 @@ iferr@^0.1.5: resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= +iferr@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/iferr/-/iferr-1.0.2.tgz#e9fde49a9da06dc4a4194c6c9ed6d08305037a6d" + integrity sha512-9AfeLfji44r5TKInjhz3W9DyZI1zR1JAf2hVBMGhddAKPqBsupb89jGfbCTHIGZd6fGZl9WlHdn4AObygyMKwg== + +ignore-walk@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.4.tgz#c9a09f69b7c7b479a5d74ac1a3c0d4236d2a6335" + integrity sha512-PY6Ii8o1jMRA1z4F2hRkH/xN59ox43DavKvD3oDpfurRlOJyAHpifIwpbdv1n4jt4ov0jSpw3kQ4GhJnpBL6WQ== + dependencies: + minimatch "^3.0.4" + ignore@^4.0.3, ignore@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" @@ -16916,10 +17071,10 @@ ignore@^5.2.0: resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== -immer@8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/immer/-/immer-8.0.1.tgz#9c73db683e2b3975c424fb0572af5889877ae656" - integrity sha512-aqXhGP7//Gui2+UrEtvxZxSquQVXTpZ7KDxfCcKAF3Vysvw0CViVaW9RZ1j1xlIYqaaaipBoqdqeibkc18PNvA== +immer@8.0.1, immer@^9.0.6: + version "9.0.21" + resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.21.tgz#1e025ea31a40f24fb064f1fef23e931496330176" + integrity sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA== immutable@^4.0.0: version "4.1.0" @@ -16952,7 +17107,7 @@ import-local@^3.0.2: pkg-dir "^4.2.0" resolve-cwd "^3.0.0" -imurmurhash@^0.1.4: +imurmurhash@*, imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= @@ -16994,7 +17149,7 @@ inflection@^1.13.2, inflection@~1.13.1: resolved "https://registry.yarnpkg.com/inflection/-/inflection-1.13.4.tgz#65aa696c4e2da6225b148d7a154c449366633a32" integrity sha512-6I/HUDeYFfuNCVS3td055BaXBwKYuzw7K3ExVMStBowKo9oOAMJIXIHvdyR3iboTCp1b+1i5DSkIZTcwIktuDw== -inflight@^1.0.4: +inflight@^1.0.4, inflight@~1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= @@ -17027,6 +17182,20 @@ ini@^1.3.4, ini@^1.3.5, ini@^1.3.8, ini@~1.3.0: resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== +init-package-json@^1.10.3: + version "1.10.3" + resolved "https://registry.yarnpkg.com/init-package-json/-/init-package-json-1.10.3.tgz#45ffe2f610a8ca134f2bd1db5637b235070f6cbe" + integrity sha512-zKSiXKhQveNteyhcj1CoOP8tqp1QuxPIPBl8Bid99DGLFqA1p87M6lNgfjJHSBoWJJlidGOv5rWjyYKEB3g2Jw== + dependencies: + glob "^7.1.1" + npm-package-arg "^4.0.0 || ^5.0.0 || ^6.0.0" + promzard "^0.3.0" + read "~1.0.1" + read-package-json "1 || 2" + semver "2.x || 3.x || 4 || 5" + validate-npm-package-license "^3.0.1" + validate-npm-package-name "^3.0.0" + inline-source-map-comment@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/inline-source-map-comment/-/inline-source-map-comment-1.0.5.tgz#50a8a44c2a790dfac441b5c94eccd5462635faf6" @@ -17122,11 +17291,21 @@ invariant@^2.2.2, invariant@^2.2.3, invariant@^2.2.4: dependencies: loose-envify "^1.0.0" -ip@^1.1.5: +ip-regex@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" + integrity sha512-58yWmlHpp7VYfcdTwMTvwMmqx/Elfxjd9RXTDyMsbL7lLWmhMylLEqiYVLKuLzOZqVgiWXD9MfR62Vv89VRxkw== + +ip@1.1.5, ip@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" integrity sha512-rBtCAQAJm8A110nbwn6YdveUnuZH3WrC36IwkRXxDnq53JvXA2NVQvB7IHyKomxK1MJ4VDNw3UtFDdXQ+AvLYA== +ip@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da" + integrity sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ== + ipaddr.js@1.9.1: version "1.9.1" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" @@ -17219,6 +17398,13 @@ is-callable@^1.1.4, is-callable@^1.2.3, is-callable@^1.2.4: resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w== +is-ci@^1.0.10: + version "1.2.1" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c" + integrity sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg== + dependencies: + ci-info "^1.5.0" + is-ci@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" @@ -17226,6 +17412,13 @@ is-ci@^2.0.0: dependencies: ci-info "^2.0.0" +is-cidr@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/is-cidr/-/is-cidr-3.1.1.tgz#e92ef121bdec2782271a77ce487a8b8df3718ab7" + integrity sha512-Gx+oErgq1j2jAKCR2Kbq0b3wbH0vQKqZ0wOlHxm0o56nq51Cs/DZA8oz9dMDhbHyHEGgJ86eTeVudtgMMOx3Mw== + dependencies: + cidr-regex "^2.0.10" + is-core-module@^2.2.0: version "2.5.0" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.5.0.tgz#f754843617c70bfd29b7bd87327400cda5c18491" @@ -17368,7 +17561,7 @@ is-glob@^2.0.0: dependencies: is-extglob "^1.0.0" -is-glob@^3.0.0, is-glob@^3.1.0: +is-glob@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= @@ -17394,6 +17587,14 @@ is-hexadecimal@^1.0.0: resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz#cc35c97588da4bd49a8eedd6bc4082d44dcb23a7" integrity sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw== +is-installed-globally@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.1.0.tgz#0dfd98f5a9111716dd535dda6492f67bf3d25a80" + integrity sha512-ERNhMg+i/XgDwPIPF3u24qpajVreaiSuvpb1Uu0jugw7KKcxGyCX8cgp8P5fwTmAuXku6beDHHECdKArjlg7tw== + dependencies: + global-dirs "^0.1.0" + is-path-inside "^1.0.0" + 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" @@ -17429,6 +17630,11 @@ is-negative-zero@^2.0.1: resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24" integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w== +is-npm@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" + integrity sha512-9r39FIr3d+KD9SbX0sfMsHzb5PP3uimOiwr3YupUaUFG4W0l1U57Rx3utpttV7qz5U3jmrO5auUa04LU9pyHsg== + is-npm@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-5.0.0.tgz#43e8d65cc56e1b67f8d47262cf667099193f45a8" @@ -17453,6 +17659,11 @@ is-number@^7.0.0: resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== +is-obj@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + integrity sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg== + is-obj@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" @@ -17463,6 +17674,13 @@ is-object@^1.0.1: resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.2.tgz#a56552e1c665c9e950b4a025461da87e72f86fcf" integrity sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA== +is-path-inside@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" + integrity sha512-qhsCR/Esx4U4hg/9I19OVUAJkGWtjRYHMRgUMZE2TDdj+Ag+kttZanLupfddNyglzz50cUlmWzUaI37GDfNx/g== + dependencies: + path-is-inside "^1.0.1" + 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" @@ -17483,7 +17701,7 @@ is-plain-object@5.0.0, is-plain-object@^5.0.0: resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== -is-plain-object@^2.0.3, is-plain-object@^2.0.4: +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== @@ -17495,6 +17713,11 @@ is-potential-custom-element-name@^1.0.1: resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== +is-primitive@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-3.0.1.tgz#98c4db1abff185485a657fc2905052b940524d05" + integrity sha512-GljRxhWvlCNRfZyORiH77FwdFwGcMO620o37EOYC0ORWdq+WYNVqW0w2Juzew4M+L81l6/QS3t5gkkihyRqv9w== + is-reference@^1.1.0: version "1.2.1" resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-1.2.1.tgz#8b2dac0b371f4bc994fdeaba9eb542d03002d0b7" @@ -18243,7 +18466,7 @@ jest@^27.4.7: import-local "^3.0.2" jest-cli "^27.4.7" -jpeg-js@^0.4.2: +jpeg-js@^0.4.2, jpeg-js@^0.4.4: version "0.4.4" resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.4.4.tgz#a9f1c6f1f9f0fa80cdb3484ed9635054d28936aa" integrity sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg== @@ -18403,17 +18626,12 @@ json-api-serializer@^2.6.0: dependencies: setimmediate "^1.0.5" -json-buffer@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" - integrity sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ== - json-buffer@3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== -json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: +json-parse-better-errors@^1.0.0, json-parse-better-errors@^1.0.1, 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== @@ -18440,10 +18658,10 @@ json-schema-traverse@^1.0.0: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== -json-schema@0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - integrity sha512-a3xHnILGMtk+hDOqNwHzF6e2fNbiMrXZvxKQiEv2MlgQP+pjIOzqAmKYD2mDpXYE/44M7g+n9p2bKkYWDUcXCQ== +json-schema@0.2.3, 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-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" @@ -18457,7 +18675,7 @@ json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1: dependencies: jsonify "~0.0.0" -json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.0, json-stringify-safe@~5.0.1: +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 sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= @@ -18467,13 +18685,6 @@ json5@^0.5.1: resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= -json5@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593" - integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA== - dependencies: - minimist "^1.2.0" - json5@^2.1.2, json5@^2.1.3, json5@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" @@ -18515,6 +18726,16 @@ jsonlint@^1.6.3: JSV "^4.0.x" nomnom "^1.5.x" +jsonparse@^1.2.0, jsonparse@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" + integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg== + +jsonpointer@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-5.0.0.tgz#f802669a524ec4805fa7389eadbc9921d5dc8072" + integrity sha512-PNYZIdMjVIvVgDSYKTT63Y+KZ6IZvGRNNWcxwD+GNnUz1MKPfv30J8ueCjdwcN0nDx2SlshgyB7Oy0epAzVRRg== + jsprim@^1.2.2: version "1.4.1" resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" @@ -18535,13 +18756,6 @@ just-extend@^4.0.2: resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-4.2.1.tgz#ef5e589afb61e5d66b24eca749409a8939a8c744" integrity sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg== -keyv@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" - integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA== - dependencies: - json-buffer "3.0.0" - keyv@^4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.0.3.tgz#4f3aa98de254803cafcd2896734108daa35e4254" @@ -18607,6 +18821,13 @@ language-tags@^1.0.5: dependencies: language-subtag-registry "~0.3.2" +latest-version@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-3.1.0.tgz#a205383fea322b33b5ae3b18abee0dc2f356ee15" + integrity sha512-Be1YRHWWlZaSsrz2U+VInk+tO0EwLIyV+23RhWLINJYwg/UIikxjlj3MhH37/6/EDCAusjajvMkMMUXRaMWl/w== + dependencies: + package-json "^4.0.0" + latest-version@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-5.1.0.tgz#119dfe908fe38d15dfa43ecd13fa12ec8832face" @@ -18614,6 +18835,11 @@ latest-version@^5.1.0: dependencies: package-json "^6.3.0" +lazy-property@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lazy-property/-/lazy-property-1.0.0.tgz#84ddc4b370679ba8bd4cdcfa4c06b43d57111147" + integrity sha512-O52TK7FHpBPzdtvc5GoF0EPLQIBMqrAupANPGBidPkrDpl9IXlzuma3T+m0o0OpkRVPmTu3SDoT7985lw4KbNQ== + lazy-universal-dotenv@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/lazy-universal-dotenv/-/lazy-universal-dotenv-3.0.1.tgz#a6c8938414bca426ab8c9463940da451a911db38" @@ -18655,6 +18881,140 @@ levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" +libcipm@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/libcipm/-/libcipm-4.0.8.tgz#dcea4919e10dfbce420327e63901613b9141bc89" + integrity sha512-IN3hh2yDJQtZZ5paSV4fbvJg4aHxCCg5tcZID/dSVlTuUiWktsgaldVljJv6Z5OUlYspx6xQkbR0efNodnIrOA== + dependencies: + bin-links "^1.1.2" + bluebird "^3.5.1" + figgy-pudding "^3.5.1" + find-npm-prefix "^1.0.2" + graceful-fs "^4.1.11" + ini "^1.3.5" + lock-verify "^2.1.0" + mkdirp "^0.5.1" + npm-lifecycle "^3.0.0" + npm-logical-tree "^1.2.1" + npm-package-arg "^6.1.0" + pacote "^9.1.0" + read-package-json "^2.0.13" + rimraf "^2.6.2" + worker-farm "^1.6.0" + +libnpm@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/libnpm/-/libnpm-3.0.1.tgz#0be11b4c9dd4d1ffd7d95c786e92e55d65be77a2" + integrity sha512-d7jU5ZcMiTfBqTUJVZ3xid44fE5ERBm9vBnmhp2ECD2Ls+FNXWxHSkO7gtvrnbLO78gwPdNPz1HpsF3W4rjkBQ== + dependencies: + bin-links "^1.1.2" + bluebird "^3.5.3" + find-npm-prefix "^1.0.2" + libnpmaccess "^3.0.2" + libnpmconfig "^1.2.1" + libnpmhook "^5.0.3" + libnpmorg "^1.0.1" + libnpmpublish "^1.1.2" + libnpmsearch "^2.0.2" + libnpmteam "^1.0.2" + lock-verify "^2.0.2" + npm-lifecycle "^3.0.0" + npm-logical-tree "^1.2.1" + npm-package-arg "^6.1.0" + npm-profile "^4.0.2" + npm-registry-fetch "^4.0.0" + npmlog "^4.1.2" + pacote "^9.5.3" + read-package-json "^2.0.13" + stringify-package "^1.0.0" + +libnpmaccess@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/libnpmaccess/-/libnpmaccess-3.0.2.tgz#8b2d72345ba3bef90d3b4f694edd5c0417f58923" + integrity sha512-01512AK7MqByrI2mfC7h5j8N9V4I7MHJuk9buo8Gv+5QgThpOgpjB7sQBDDkeZqRteFb1QM/6YNdHfG7cDvfAQ== + dependencies: + aproba "^2.0.0" + get-stream "^4.0.0" + npm-package-arg "^6.1.0" + npm-registry-fetch "^4.0.0" + +libnpmconfig@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/libnpmconfig/-/libnpmconfig-1.2.1.tgz#c0c2f793a74e67d4825e5039e7a02a0044dfcbc0" + integrity sha512-9esX8rTQAHqarx6qeZqmGQKBNZR5OIbl/Ayr0qQDy3oXja2iFVQQI81R6GZ2a02bSNZ9p3YOGX1O6HHCb1X7kA== + dependencies: + figgy-pudding "^3.5.1" + find-up "^3.0.0" + ini "^1.3.5" + +libnpmhook@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/libnpmhook/-/libnpmhook-5.0.3.tgz#4020c0f5edbf08ebe395325caa5ea01885b928f7" + integrity sha512-UdNLMuefVZra/wbnBXECZPefHMGsVDTq5zaM/LgKNE9Keyl5YXQTnGAzEo+nFOpdRqTWI9LYi4ApqF9uVCCtuA== + dependencies: + aproba "^2.0.0" + figgy-pudding "^3.4.1" + get-stream "^4.0.0" + npm-registry-fetch "^4.0.0" + +libnpmorg@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/libnpmorg/-/libnpmorg-1.0.1.tgz#5d2503f6ceb57f33dbdcc718e6698fea6d5ad087" + integrity sha512-0sRUXLh+PLBgZmARvthhYXQAWn0fOsa6T5l3JSe2n9vKG/lCVK4nuG7pDsa7uMq+uTt2epdPK+a2g6btcY11Ww== + dependencies: + aproba "^2.0.0" + figgy-pudding "^3.4.1" + get-stream "^4.0.0" + npm-registry-fetch "^4.0.0" + +libnpmpublish@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/libnpmpublish/-/libnpmpublish-1.1.3.tgz#e3782796722d79eef1a0a22944c117e0c4ca4280" + integrity sha512-/3LsYqVc52cHXBmu26+J8Ed7sLs/hgGVFMH1mwYpL7Qaynb9RenpKqIKu0sJ130FB9PMkpMlWjlbtU8A4m7CQw== + dependencies: + aproba "^2.0.0" + figgy-pudding "^3.5.1" + get-stream "^4.0.0" + lodash.clonedeep "^4.5.0" + normalize-package-data "^2.4.0" + npm-package-arg "^6.1.0" + npm-registry-fetch "^4.0.0" + semver "^5.5.1" + ssri "^6.0.1" + +libnpmsearch@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/libnpmsearch/-/libnpmsearch-2.0.2.tgz#9a4f059102d38e3dd44085bdbfe5095f2a5044cf" + integrity sha512-VTBbV55Q6fRzTdzziYCr64+f8AopQ1YZ+BdPOv16UegIEaE8C0Kch01wo4s3kRTFV64P121WZJwgmBwrq68zYg== + dependencies: + figgy-pudding "^3.5.1" + get-stream "^4.0.0" + npm-registry-fetch "^4.0.0" + +libnpmteam@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/libnpmteam/-/libnpmteam-1.0.2.tgz#8b48bcbb6ce70dd8150c950fcbdbf3feb6eec820" + integrity sha512-p420vM28Us04NAcg1rzgGW63LMM6rwe+6rtZpfDxCcXxM0zUTLl7nPFEnRF3JfFBF5skF/yuZDUthTsHgde8QA== + dependencies: + aproba "^2.0.0" + figgy-pudding "^3.4.1" + get-stream "^4.0.0" + npm-registry-fetch "^4.0.0" + +libnpx@^10.2.4: + version "10.2.4" + resolved "https://registry.yarnpkg.com/libnpx/-/libnpx-10.2.4.tgz#ef0e3258e29aef2ec7ee3276115e20e67f67d4ee" + integrity sha512-BPc0D1cOjBeS8VIBKUu5F80s6njm0wbVt7CsGMrIcJ+SI7pi7V0uVPGpEMH9H5L8csOcclTxAXFE2VAsJXUhfA== + dependencies: + dotenv "^5.0.1" + npm-package-arg "^6.0.0" + rimraf "^2.6.2" + safe-buffer "^5.1.0" + update-notifier "^2.3.0" + which "^1.3.0" + y18n "^4.0.0" + yargs "^14.2.3" + license-checker@^25.0.1: version "25.0.1" resolved "https://registry.yarnpkg.com/license-checker/-/license-checker-25.0.1.tgz#4d14504478a5240a857bb3c21cd0491a00d761fa" @@ -18694,13 +19054,6 @@ lines-and-columns@^1.1.6: resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= -linkify-it@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-2.2.0.tgz#e3b54697e78bf915c70a38acd78fd09e0058b1cf" - integrity sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw== - dependencies: - uc.micro "^1.0.1" - linkify-it@^3.0.1: version "3.0.2" resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-3.0.2.tgz#f55eeb8bc1d3ae754049e124ab3bb56d97797fb8" @@ -18708,20 +19061,6 @@ linkify-it@^3.0.1: dependencies: uc.micro "^1.0.1" -linkify-it@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-4.0.1.tgz#01f1d5e508190d06669982ba31a7d9f56a5751ec" - integrity sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw== - dependencies: - uc.micro "^1.0.1" - -linkify-it@~1.2.0: - version "1.2.4" - resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-1.2.4.tgz#0773526c317c8fd13bd534ee1d180ff88abf881a" - integrity sha512-eGHwtlABkp1NOJSiKUNqBf3SYAS5jPHtvRXPAgNaQwTqmkTahjtiLH9NtxdR5IOPhNvwNMN/diswSfZKzUkhGg== - dependencies: - uc.micro "^1.0.1" - lint-staged@^13.0.2: version "13.0.2" resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-13.0.2.tgz#35a1c57130e9ad5b1dea784972a40777ba433dd5" @@ -18801,25 +19140,7 @@ loader-runner@^4.2.0: resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.2.0.tgz#d7022380d66d14c5fb1d496b89864ebcfd478384" integrity sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw== -loader-utils@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.0.tgz#e4cace5b816d425a166b5f097e10cd12b36064b0" - integrity sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ== - dependencies: - big.js "^5.2.2" - emojis-list "^3.0.0" - json5 "^2.1.2" - -loader-utils@^1.2.3, loader-utils@^1.4.0: - version "1.4.2" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.2.tgz#29a957f3a63973883eb684f10ffd3d151fec01a3" - integrity sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg== - dependencies: - big.js "^5.2.2" - emojis-list "^3.0.0" - json5 "^1.0.1" - -loader-utils@^2.0.0: +loader-utils@2.0.0, loader-utils@^1.2.3, loader-utils@^1.4.0, loader-utils@^2.0.0, 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== @@ -18880,6 +19201,22 @@ locate-path@^7.1.0: dependencies: p-locate "^6.0.0" +lock-verify@^2.0.2, lock-verify@^2.1.0, lock-verify@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/lock-verify/-/lock-verify-2.2.2.tgz#9e93c0999dc3cbbede4f16f9cfdaa93ead8c76ef" + integrity sha512-2CUNtr1ZSVKJHcYP8uEzafmmuyauCB5zZimj8TvQd/Lflt9kXVZs+8S+EbAzZLaVUDn8CYGmeC3DFGdYfnCzeQ== + dependencies: + "@iarna/cli" "^2.1.0" + npm-package-arg "^6.1.0" + semver "^5.4.1" + +lockfile@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/lockfile/-/lockfile-1.0.4.tgz#07f819d25ae48f87e538e6578b6964a4981a5609" + integrity sha512-cvbTwETRfsFh4nHsL1eGWapU1XFi5Ot9E85sWAwia7Y7EgB7vfqcZhTKZ+l7hCGxSPoushMv5GKhT5PdLv03WA== + dependencies: + signal-exit "^3.0.2" + lodash-es@^4.17.11: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee" @@ -18906,11 +19243,29 @@ lodash._baseflatten@^3.0.0: lodash.isarguments "^3.0.0" lodash.isarray "^3.0.0" -lodash._bindcallback@^3.0.0: +lodash._baseindexof@*: + version "3.1.0" + resolved "https://registry.yarnpkg.com/lodash._baseindexof/-/lodash._baseindexof-3.1.0.tgz#fe52b53a1c6761e42618d654e4a25789ed61822c" + integrity sha512-bSYo8Pc/f0qAkr8fPJydpJjtrHiSynYfYBjtANIgXv5xEf1WlTC63dIDlgu0s9dmTvzRu1+JJTxcIAHe+sH0FQ== + +lodash._baseuniq@~4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash._baseuniq/-/lodash._baseuniq-4.6.0.tgz#0ebb44e456814af7905c6212fa2c9b2d51b841e8" + integrity sha512-Ja1YevpHZctlI5beLA7oc5KNDhGcPixFhcqSiORHNsp/1QTv7amAXzw+gu4YOvErqVlMVyIJGgtzeepCnnur0A== + dependencies: + lodash._createset "~4.0.0" + lodash._root "~3.0.0" + +lodash._bindcallback@*, lodash._bindcallback@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz#e531c27644cf8b57a99e17ed95b35c748789392e" integrity sha512-2wlI0JRAGX8WEf4Gm1p/mv/SZ+jLijpj0jyaE/AXeuQphzCgD8ZQW4oSpoN8JAopujOFGU3KMuq7qfHBWlGpjQ== +lodash._cacheindexof@*: + version "3.0.2" + resolved "https://registry.yarnpkg.com/lodash._cacheindexof/-/lodash._cacheindexof-3.0.2.tgz#3dc69ac82498d2ee5e3ce56091bafd2adc7bde92" + integrity sha512-S8dUjWr7SUT/X6TBIQ/OYoCHo1Stu1ZRy6uMUSKqzFnZp5G5RyQizSm6kvxD2Ewyy6AVfMg4AToeZzKfF99T5w== + lodash._createassigner@^3.0.0: version "3.1.1" resolved "https://registry.yarnpkg.com/lodash._createassigner/-/lodash._createassigner-3.1.1.tgz#838a5bae2fdaca63ac22dee8e19fa4e6d6970b11" @@ -18920,7 +19275,19 @@ lodash._createassigner@^3.0.0: lodash._isiterateecall "^3.0.0" lodash.restparam "^3.0.0" -lodash._getnative@^3.0.0: +lodash._createcache@*: + version "3.1.2" + resolved "https://registry.yarnpkg.com/lodash._createcache/-/lodash._createcache-3.1.2.tgz#56d6a064017625e79ebca6b8018e17440bdcf093" + integrity sha512-ev5SP+iFpZOugyab/DEUQxUeZP5qyciVTlgQ1f4Vlw7VUcCD8fVnyIqVUEIaoFH9zjAqdgi69KiofzvVmda/ZQ== + dependencies: + lodash._getnative "^3.0.0" + +lodash._createset@~4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/lodash._createset/-/lodash._createset-4.0.3.tgz#0f4659fbb09d75194fa9e2b88a6644d363c9fe26" + integrity sha512-GTkC6YMprrJZCYU3zcqZj+jkXkrXzq3IPBcF/fIPpNEAB4hZEtXU8zp/RwKOvZl43NUmwDbyRk3+ZTbeRdEBXA== + +lodash._getnative@*, lodash._getnative@^3.0.0: version "3.9.1" resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" integrity sha512-RrL9VxMEPyDMHOd9uFbvMe8X55X16/cGM5IgOKgRElQZutpX89iS6vwl64duTV1/16w5JY7tuFNXqoekmh1EmA== @@ -18935,6 +19302,11 @@ lodash._reinterpolate@^3.0.0: resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= +lodash._root@~3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._root/-/lodash._root-3.0.1.tgz#fba1c4524c19ee9a5f8136b4609f017cf4ded692" + integrity sha512-O0pWuFSK6x4EXhM1dhZ8gchNtG7JMqBtrHdoUFUWXD7dJnNSUze1GuyQr5sOs0aCvgGeI3o/OJW8f4ca7FDxmQ== + lodash.assign@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-3.2.0.tgz#3ce9f0234b4b2223e296b8fa0ac1fee8ebca64fa" @@ -18964,7 +19336,7 @@ lodash.castarray@^4.4.0: resolved "https://registry.yarnpkg.com/lodash.castarray/-/lodash.castarray-4.4.0.tgz#c02513515e309daddd4c24c60cfddcf5976d9115" integrity sha1-wCUTUV4wna3dTCTGDP3c9ZdtkRU= -lodash.clonedeep@^4.4.1, lodash.clonedeep@^4.5.0: +lodash.clonedeep@^4.4.1, lodash.clonedeep@^4.5.0, lodash.clonedeep@~4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" integrity sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ== @@ -19128,7 +19500,7 @@ lodash.pick@^4.4.0: resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3" integrity sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q== -lodash.restparam@^3.0.0: +lodash.restparam@*, lodash.restparam@^3.0.0: version "3.6.1" resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" integrity sha512-L4/arjjuq4noiUJpt3yS6KIKDtJwNe2fIYgMqyYYKoeIfV1iEqvPwhCx23o+R9dzouGihDAPN1dTIRWa7zk8tw== @@ -19158,7 +19530,12 @@ lodash.truncate@^4.4.2: resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM= -lodash.uniq@4.5.0, lodash.uniq@^4.2.0, lodash.uniq@^4.5.0: +lodash.union@~4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.union/-/lodash.union-4.6.0.tgz#48bb5088409f16f1821666641c44dd1aaae3cd88" + integrity sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw== + +lodash.uniq@4.5.0, lodash.uniq@^4.2.0, lodash.uniq@^4.5.0, lodash.uniq@~4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" integrity sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ== @@ -19173,6 +19550,11 @@ lodash.values@^4.3.0: resolved "https://registry.yarnpkg.com/lodash.values/-/lodash.values-4.3.0.tgz#a3a6c2b0ebecc5c2cba1c17e6e620fe81b53d347" integrity sha512-r0RwvdCv8id9TUblb/O7rYPwVy6lerCbcawrfdo9iC/1t1wsNMJknO79WNBgwkH0hIeJ08jmvvESbFpNb4jH0Q== +lodash.without@~4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.without/-/lodash.without-4.4.0.tgz#3cd4574a00b67bae373a94b748772640507b7aac" + integrity sha512-M3MefBwfDhgKgINVuBJCO1YR3+gf6s9HNJsIiZ/Ru77Ws6uTb9eBuvrkpzO+9iLoAaRodGuq7tyrPCx+74QYGQ== + lodash@^4.17.10, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4, lodash@^4.7.0: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" @@ -19235,11 +19617,6 @@ lower-case@^2.0.2: dependencies: tslib "^2.0.3" -lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" - integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== - lowercase-keys@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" @@ -19253,6 +19630,14 @@ lowlight@^1.14.0, lowlight@^1.17.0: fault "^1.0.0" highlight.js "~10.7.0" +lru-cache@^4.0.1: + 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" @@ -19267,12 +19652,7 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" -lru-cache@^7.5.1: - version "7.18.3" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.18.3.tgz#f793896e0fd0e954a59dfdd82f0773808df6aa89" - integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA== - -lzma-native@^8.0.5: +lzma-native@^8.0.5, lzma-native@^8.0.6: version "8.0.6" resolved "https://registry.yarnpkg.com/lzma-native/-/lzma-native-8.0.6.tgz#3ea456209d643bafd9b5d911781bdf0b396b2665" integrity sha512-09xfg67mkL2Lz20PrrDeNYZxzeW7ADtpYFbwSQh9U8+76RIzx5QsJBMy8qikv3hbUPfpy6hqwxt6FcGK81g9AA== @@ -19295,6 +19675,13 @@ magic-string@^0.25.7: dependencies: sourcemap-codec "^1.4.4" +make-dir@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" + integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== + dependencies: + pify "^3.0.0" + make-dir@^2.0.0, make-dir@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" @@ -19310,6 +19697,44 @@ make-dir@^3.0.0, make-dir@^3.0.2, make-dir@^3.1.0: dependencies: semver "^6.0.0" +make-fetch-happen@^5.0.0: + version "5.0.2" + resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-5.0.2.tgz#aa8387104f2687edca01c8687ee45013d02d19bd" + integrity sha512-07JHC0r1ykIoruKO8ifMXu+xEU8qOXDFETylktdug6vJDACnP+HKevOu3PXyNPzFyTSlz8vrBYlBO1JZRe8Cag== + dependencies: + agentkeepalive "^3.4.1" + cacache "^12.0.0" + http-cache-semantics "^3.8.1" + http-proxy-agent "^2.1.0" + https-proxy-agent "^2.2.3" + lru-cache "^5.1.1" + mississippi "^3.0.0" + node-fetch-npm "^2.0.2" + promise-retry "^1.1.1" + socks-proxy-agent "^4.0.0" + ssri "^6.0.0" + +make-fetch-happen@^8.0.9: + version "8.0.14" + resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-8.0.14.tgz#aaba73ae0ab5586ad8eaa68bd83332669393e222" + integrity sha512-EsS89h6l4vbfJEtBZnENTOFk8mCRpY5ru36Xe5bcX1KYIli2mkSHqoFsp5O1wMDvTJJzxe/4THpCTtygjeeGWQ== + dependencies: + agentkeepalive "^4.1.3" + cacache "^15.0.5" + http-cache-semantics "^4.1.0" + http-proxy-agent "^4.0.1" + https-proxy-agent "^5.0.0" + is-lambda "^1.0.1" + lru-cache "^6.0.0" + minipass "^3.1.3" + minipass-collect "^1.0.2" + minipass-fetch "^1.3.2" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.4" + promise-retry "^2.0.1" + socks-proxy-agent "^5.0.0" + ssri "^8.0.0" + make-fetch-happen@^9.1.0: version "9.1.0" resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz#53085a09e7971433e6765f7971bf63f4e05cb968" @@ -19394,7 +19819,7 @@ markdown-it-terminal@0.2.1: lodash.merge "^4.6.2" markdown-it "^8.3.1" -markdown-it@^12.2.0: +markdown-it@^12.2.0, markdown-it@^12.3.2, markdown-it@^13.0.1, markdown-it@^4.3.0, markdown-it@^8.3.1: version "12.3.2" resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-12.3.2.tgz#bf92ac92283fe983fe4de8ff8abfb5ad72cd0c90" integrity sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg== @@ -19405,39 +19830,6 @@ markdown-it@^12.2.0: mdurl "^1.0.1" uc.micro "^1.0.5" -markdown-it@^13.0.1: - version "13.0.1" - resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-13.0.1.tgz#c6ecc431cacf1a5da531423fc6a42807814af430" - integrity sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q== - dependencies: - argparse "^2.0.1" - entities "~3.0.1" - linkify-it "^4.0.1" - mdurl "^1.0.1" - uc.micro "^1.0.5" - -markdown-it@^4.3.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-4.4.0.tgz#3df373dbea587a9a7fef3e56311b68908f75c414" - integrity sha512-Rl8dHHeLuAh3E72OPY0tY7CLvlxgHiLhlshIYswAAabAg4YDBLa6e/LTgNkkxBO2K61ESzoquPQFMw/iMrT1PA== - dependencies: - argparse "~1.0.2" - entities "~1.1.1" - linkify-it "~1.2.0" - mdurl "~1.0.0" - uc.micro "^1.0.0" - -markdown-it@^8.3.1: - version "8.4.2" - resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-8.4.2.tgz#386f98998dc15a37722aa7722084f4020bdd9b54" - integrity sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ== - dependencies: - argparse "^1.0.7" - entities "~1.1.1" - linkify-it "^2.0.0" - mdurl "^1.0.1" - uc.micro "^1.0.5" - markdown-table@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/markdown-table/-/markdown-table-2.0.0.tgz#194a90ced26d31fe753d8b9434430214c011865b" @@ -19641,17 +20033,22 @@ mdn-links@^0.1.0: resolved "https://registry.yarnpkg.com/mdn-links/-/mdn-links-0.1.0.tgz#e24c83b97cb4c5886cc39f2f780705fbfe273aa5" integrity sha1-4kyDuXy0xYhsw58veAcF+/4nOqU= -mdurl@^1.0.0, mdurl@^1.0.1, mdurl@~1.0.0: +mdurl@^1.0.0, mdurl@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" integrity sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4= +meant@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/meant/-/meant-1.0.3.tgz#67769af9de1d158773e928ae82c456114903554c" + integrity sha512-88ZRGcNxAq4EH38cQ4D85PM57pikCwS8Z99EWHODxN7KBY+UuPiqzRTtZzS8KTXO/ywSWbdjjJST2Hly/EQxLw== + 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== -mem@^4.3.0: +mem@^4.0.0, mem@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178" integrity sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w== @@ -19913,11 +20310,6 @@ mime-types@^2.1.25: dependencies: mime-db "1.50.0" -mime-types@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-1.0.2.tgz#995ae1392ab8affcbfcb2641dd054e943c0d5dce" - integrity sha512-echfutj/t5SoTL4WZpqjA1DCud1XO0WQF3/GJ48YBmc4ZMhCK77QA6Z/w6VTQERLKuJ4drze3kw2TUT8xZXVNw== - 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" @@ -19935,11 +20327,6 @@ mime@^2.0.3, mime@^2.4.4, mime@^2.4.6: resolved "https://registry.yarnpkg.com/mime/-/mime-2.5.2.tgz#6e3dc6cc2b9510643830e5f19d5cb753da5eeabe" integrity sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg== -mime@~1.2.11: - version "1.2.11" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.2.11.tgz#58203eed86e3a5ef17aed2b7d9ebd47f0a60dd10" - integrity sha512-Ysa2F/nqTNGHhhm9MV8ure4+Hc+Y8AWiqUdHxsO7xu8zc92ND9f3kpALHjaP026Ft17UfxrMt95c50PLUeynBw== - mimic-fn@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" @@ -19955,7 +20342,7 @@ mimic-fn@^4.0.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-4.0.0.tgz#60a90550d5cb0b239cca65d893b1a53b29871ecc" integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== -mimic-response@^1.0.0, mimic-response@^1.0.1: +mimic-response@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== @@ -19994,20 +20381,13 @@ minimalistic-crypto-utils@^1.0.1: resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= -"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.4, minimatch@^3.1.2: +"minimatch@2 || 3", minimatch@3.0.4, minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: 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" -minimatch@3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== - dependencies: - brace-expansion "^1.1.7" - minimatch@^5.0.1: version "5.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.2.tgz#0939d7d6f0898acbd1508abe534d1929368a8fff" @@ -20031,17 +20411,7 @@ minimist-options@4.1.0: is-plain-obj "^1.1.0" kind-of "^6.0.3" -minimist@1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" - integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== - -minimist@^0.2.1: - version "0.2.4" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.2.4.tgz#0085d5501e29033748a2f2a4da0180142697a475" - integrity sha512-Pkrrm8NjyQ8yVt8Am9M+yUt74zE3iokhzbG1bFVNjLB92vwM71hf40RkEsryg98BujhVOncKm/C1xROxZ030LQ== - -minimist@^1.1.0, minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6: +minimist@1.2.5, minimist@^0.2.1, minimist@^1.1.0, minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6: version "1.2.6" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== @@ -20053,7 +20423,7 @@ minipass-collect@^1.0.2: dependencies: minipass "^3.0.0" -minipass-fetch@^1.3.2: +minipass-fetch@^1.3.0, minipass-fetch@^1.3.2: version "1.4.1" resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-1.4.1.tgz#d75e0091daac1b0ffd7e9d41629faff7d0c1f1b6" integrity sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw== @@ -20071,6 +20441,14 @@ minipass-flush@^1.0.5: dependencies: minipass "^3.0.0" +minipass-json-stream@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minipass-json-stream/-/minipass-json-stream-1.0.1.tgz#7edbb92588fbfc2ff1db2fc10397acb7b6b44aa7" + integrity sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg== + dependencies: + jsonparse "^1.3.1" + minipass "^3.0.0" + minipass-pipeline@^1.2.2, minipass-pipeline@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz#68472f79711c084657c067c5c6ad93cddea8214c" @@ -20085,7 +20463,7 @@ minipass-sized@^1.0.3: dependencies: minipass "^3.0.0" -minipass@^2.2.0: +minipass@^2.2.0, minipass@^2.3.5: version "2.9.0" resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== @@ -20190,7 +20568,7 @@ mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.4, mkdirp@^0.5.5, mkdir dependencies: minimist "^1.2.5" -mkdirp@^0.5.6: +mkdirp@^0.5.6, mkdirp@~0.5.0: version "0.5.6" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== @@ -20223,7 +20601,7 @@ morgan@^1.10.0: on-finished "~2.3.0" on-headers "~1.0.2" -mout@^1.0.0: +mout@^1.0.0, mout@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/mout/-/mout-1.2.4.tgz#9ffd261c4d6509e7ebcbf6b641a89b36ecdf8155" integrity sha512-mZb9uOruMWgn/fw28DG4/yE3Kehfk1zKCLhuDU2O3vlKdnBBr4XaOCqVTflJ5aODavGUPqFHZgrFX3NJVuxGhQ== @@ -20270,7 +20648,7 @@ mute-stream@0.0.7: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= -mute-stream@0.0.8: +mute-stream@0.0.8, mute-stream@~0.0.4: version "0.0.8" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== @@ -20280,10 +20658,10 @@ nan@^2.12.1: resolved "https://registry.yarnpkg.com/nan/-/nan-2.15.0.tgz#3f34a473ff18e15c1b5626b62903b5ad6e665fee" integrity sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ== -nanoid@^3.3.4: - version "3.3.4" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab" - integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw== +nanoid@^3.1.31, nanoid@^3.3.4: + version "3.3.6" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.6.tgz#443380c856d6e9f9824267d960b4236ad583ea4c" + integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA== nanomatch@^1.2.9: version "1.2.13" @@ -20382,7 +20760,16 @@ node-dir@^0.1.17: dependencies: minimatch "^3.0.2" -node-fetch@^2.6.0, node-fetch@^2.6.1: +node-fetch-npm@^2.0.2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/node-fetch-npm/-/node-fetch-npm-2.0.4.tgz#6507d0e17a9ec0be3bec516958a497cec54bf5a4" + integrity sha512-iOuIQDWDyjhv9qSDrj9aq/klt6F9z1p2otB3AV7v3zBDcL/x+OfGsvGQZZCcMZbUf4Ujw1xGNQkjvGnVT22cKg== + dependencies: + encoding "^0.1.11" + json-parse-better-errors "^1.0.0" + safe-buffer "^5.1.1" + +node-fetch@^2.6.0, node-fetch@^2.6.1, node-fetch@^2.6.7: version "2.6.9" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.9.tgz#7c7f744b5cc6eb5fd404e0c7a9fec630a55657e6" integrity sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg== @@ -20394,6 +20781,23 @@ node-gyp-build@^4.2.1: resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.4.0.tgz#42e99687ce87ddeaf3a10b99dc06abc11021f3f4" integrity sha512-amJnQCcgtRVw9SvoebO3BKGESClrfXGCUTX9hSn1OuGQTQBOZmVd0Z0OlecpuRksKvbsUqALE8jls/ErClAPuQ== +node-gyp@^5.0.2, node-gyp@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-5.1.1.tgz#eb915f7b631c937d282e33aed44cb7a025f62a3e" + integrity sha512-WH0WKGi+a4i4DUt2mHnvocex/xPLp9pYt5R6M2JdFB7pJ7Z34hveZ4nDTGTiLXCkitA9T8HFZjhinBCiVHYcWw== + dependencies: + env-paths "^2.2.0" + glob "^7.1.4" + graceful-fs "^4.2.2" + mkdirp "^0.5.1" + nopt "^4.0.1" + npmlog "^4.1.2" + request "^2.88.0" + rimraf "^2.6.3" + semver "^5.7.1" + tar "^4.4.12" + which "^1.3.1" + node-gyp@^8.4.0: version "8.4.1" resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-8.4.1.tgz#3d49308fc31f768180957d6b5746845fbd429937" @@ -20454,33 +20858,23 @@ node-modules-regexp@^1.0.0: resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= -node-notifier@^10.0.0: - version "10.0.1" - resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-10.0.1.tgz#0e82014a15a8456c4cfcdb25858750399ae5f1c7" - integrity sha512-YX7TSyDukOZ0g+gmzjB6abKu+hTGvO8+8+gIFDsRCU2t8fLV/P2unmt+LGFaIa4y64aX98Qksa97rgz4vMNeLQ== +node-notifier@^10.0.0, node-notifier@^8.0.1: + version "8.0.2" + resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-8.0.2.tgz#f3167a38ef0d2c8a866a83e318c1ba0efeb702c5" + integrity sha512-oJP/9NAdd9+x2Q+rfphB2RJCHjod70RcRLjosiPMMu5gjIfwVnOUGq2nbTjTUbmy0DJ/tFIVT30+Qe3nzl4TJg== dependencies: growly "^1.3.0" is-wsl "^2.2.0" - semver "^7.3.5" + semver "^7.3.2" shellwords "^0.1.1" - uuid "^8.3.2" + uuid "^8.3.0" which "^2.0.2" -node-releases@^1.1.61: - version "1.1.77" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.77.tgz#50b0cfede855dd374e7585bf228ff34e57c1c32e" - integrity sha512-rB1DUFUNAN4Gn9keO2K1efO35IDK7yKHCdCaIMvFO7yUYmmZYeDjnGKle26G4rwj+LKRQpjyUUvMkPglwGCYNQ== - node-releases@^2.0.8: version "2.0.10" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.10.tgz#c311ebae3b6a148c89b1813fd7c4d3c024ef537f" integrity sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w== -node-uuid@~1.4.0: - version "1.4.8" - resolved "https://registry.yarnpkg.com/node-uuid/-/node-uuid-1.4.8.tgz#b040eb0923968afabf8d32fb1f17f1167fdab907" - integrity sha512-TkCET/3rr9mUuRp+CpO7qfgT++aAxfDRaalQhwPFzI9BY/2rCDn6OfpZOVggi1AXfTPpfkTrg5f5WQx5G1uLxA== - node-watch@0.7.3: version "0.7.3" resolved "https://registry.yarnpkg.com/node-watch/-/node-watch-0.7.3.tgz#6d4db88e39c8d09d3ea61d6568d80e5975abc7ab" @@ -20501,7 +20895,7 @@ nopt@^3.0.6: dependencies: abbrev "1" -nopt@^4.0.1: +nopt@^4.0.1, nopt@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.3.tgz#a375cad9d02fd921278d954c2254d5aa57e15e48" integrity sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg== @@ -20516,7 +20910,7 @@ nopt@^5.0.0: dependencies: abbrev "1" -normalize-package-data@^2.0.0, normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package-data@^2.5.0: +normalize-package-data@^2.0.0, normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package-data@^2.4.0, normalize-package-data@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== @@ -20553,15 +20947,30 @@ normalize-range@^0.1.2: resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI= -normalize-url@^4.1.0: +normalize-url@^4.5.1, normalize-url@^6.0.1: version "4.5.1" resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.1.tgz#0dd90cf1288ee1d1313b87081c9a5932ee48518a" integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA== -normalize-url@^6.0.1: - version "6.1.0" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" - integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== +npm-audit-report@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/npm-audit-report/-/npm-audit-report-1.3.3.tgz#8226deeb253b55176ed147592a3995442f2179ed" + integrity sha512-8nH/JjsFfAWMvn474HB9mpmMjrnKb1Hx/oTAdjv4PT9iZBvBxiZ+wtDUapHCJwLqYGQVPaAfs+vL5+5k9QndXw== + dependencies: + cli-table3 "^0.5.0" + console-control-strings "^1.1.0" + +npm-bundled@^1.0.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.1.2.tgz#944c78789bd739035b70baa2ca5cc32b8d860bc1" + integrity sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ== + dependencies: + npm-normalize-package-bin "^1.0.1" + +npm-cache-filename@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/npm-cache-filename/-/npm-cache-filename-1.0.2.tgz#ded306c5b0bfc870a9e9faf823bc5f283e05ae11" + integrity sha512-5v2y1KG06izpGvZJDSBR5q1Ej+NaPDO05yAAWBJE6+3eiId0R176Gz3Qc2vEmJnE+VGul84g6Qpq8fXzD82/JA== npm-conf@^1.1.3: version "1.1.3" @@ -20576,12 +20985,48 @@ npm-git-info@^1.0.3: resolved "https://registry.yarnpkg.com/npm-git-info/-/npm-git-info-1.0.3.tgz#a933c42ec321e80d3646e0d6e844afe94630e1d5" integrity sha512-i5WBdj4F/ULl16z9ZhsJDMl1EQCMQhHZzBwNnKL2LOA+T8IHNeRkLCVz9uVV9SzUdGTbDq+1oXhIYMe+8148vw== -npm-normalize-package-bin@^1.0.0: +npm-install-checks@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/npm-install-checks/-/npm-install-checks-3.0.2.tgz#ab2e32ad27baa46720706908e5b14c1852de44d9" + integrity sha512-E4kzkyZDIWoin6uT5howP8VDvkM+E8IQDcHAycaAxMbwkqhIg5eEYALnXOl3Hq9MrkdQB/2/g1xwBINXdKSRkg== + dependencies: + semver "^2.3.0 || 3.x || 4 || 5" + +npm-lifecycle@^3.0.0, npm-lifecycle@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/npm-lifecycle/-/npm-lifecycle-3.1.5.tgz#9882d3642b8c82c815782a12e6a1bfeed0026309" + integrity sha512-lDLVkjfZmvmfvpvBzA4vzee9cn+Me4orq0QF8glbswJVEbIcSNWib7qGOffolysc3teCqbbPZZkzbr3GQZTL1g== + dependencies: + byline "^5.0.0" + graceful-fs "^4.1.15" + node-gyp "^5.0.2" + resolve-from "^4.0.0" + slide "^1.1.6" + uid-number "0.0.6" + umask "^1.1.0" + which "^1.3.1" + +npm-logical-tree@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/npm-logical-tree/-/npm-logical-tree-1.2.1.tgz#44610141ca24664cad35d1e607176193fd8f5b88" + integrity sha512-AJI/qxDB2PWI4LG1CYN579AY1vCiNyWfkiquCsJWqntRu/WwimVrC8yXeILBFHDwxfOejxewlmnvW9XXjMlYIg== + +npm-normalize-package-bin@^1.0.0, npm-normalize-package-bin@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2" integrity sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA== -npm-package-arg@^8.1.5: +"npm-package-arg@^4.0.0 || ^5.0.0 || ^6.0.0", npm-package-arg@^6.0.0, npm-package-arg@^6.1.0, npm-package-arg@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-6.1.1.tgz#02168cb0a49a2b75bf988a28698de7b529df5cb7" + integrity sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg== + dependencies: + hosted-git-info "^2.7.1" + osenv "^0.1.5" + semver "^5.6.0" + validate-npm-package-name "^3.0.0" + +npm-package-arg@^8.0.0, npm-package-arg@^8.1.5: version "8.1.5" resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-8.1.5.tgz#3369b2d5fe8fdc674baa7f1786514ddc15466e44" integrity sha512-LhgZrg0n0VgvzVdSm1oiZworPbTxYHUJCgtsJW8mGvlDpxTM1vSJc3m5QZeUkhAHIzbz3VCHd/R4osi1L1Tg/Q== @@ -20600,6 +21045,47 @@ npm-package-arg@^9.1.0: semver "^7.3.5" validate-npm-package-name "^4.0.0" +npm-packlist@^1.1.12, npm-packlist@^1.4.8: + version "1.4.8" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.8.tgz#56ee6cc135b9f98ad3d51c1c95da22bbb9b2ef3e" + integrity sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A== + dependencies: + ignore-walk "^3.0.1" + npm-bundled "^1.0.1" + npm-normalize-package-bin "^1.0.1" + +npm-pick-manifest@^3.0.0, npm-pick-manifest@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-3.0.2.tgz#f4d9e5fd4be2153e5f4e5f9b7be8dc419a99abb7" + integrity sha512-wNprTNg+X5nf+tDi+hbjdHhM4bX+mKqv6XmPh7B5eG+QY9VARfQPfCEH013H5GqfNj6ee8Ij2fg8yk0mzps1Vw== + dependencies: + figgy-pudding "^3.5.1" + npm-package-arg "^6.0.0" + semver "^5.4.1" + +npm-profile@^4.0.2, npm-profile@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/npm-profile/-/npm-profile-4.0.4.tgz#28ee94390e936df6d084263ee2061336a6a1581b" + integrity sha512-Ta8xq8TLMpqssF0H60BXS1A90iMoM6GeKwsmravJ6wYjWwSzcYBTdyWa3DZCYqPutacBMEm7cxiOkiIeCUAHDQ== + dependencies: + aproba "^1.1.2 || 2" + figgy-pudding "^3.4.1" + npm-registry-fetch "^4.0.0" + +npm-registry-fetch@^4.0.0, npm-registry-fetch@^4.0.7, npm-registry-fetch@~8.1.1: + version "8.1.5" + resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-8.1.5.tgz#33270c6722030c2d158a970d1327dcd9a149b5c5" + integrity sha512-yZPNoJK9clx1jhSXU54kU6Aj1SV2p7mXUs1W/6OjQvek3wb1RrjDCrt4iY1+VX9eBQvvSGEpzNmYkRUaTL8rqg== + dependencies: + "@npmcli/ci-detect" "^1.0.0" + lru-cache "^6.0.0" + make-fetch-happen "^8.0.9" + minipass "^3.1.3" + minipass-fetch "^1.3.0" + minipass-json-stream "^1.0.1" + minizlib "^2.0.0" + npm-package-arg "^8.0.0" + npm-run-all@^4.1.5: version "4.1.5" resolved "https://registry.yarnpkg.com/npm-run-all/-/npm-run-all-4.1.5.tgz#04476202a15ee0e2e214080861bff12a51d98fba" @@ -20643,7 +21129,133 @@ npm-run-path@^5.1.0: dependencies: path-key "^4.0.0" -npmlog@^4.1.2: +npm-user-validate@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/npm-user-validate/-/npm-user-validate-1.0.1.tgz#31428fc5475fe8416023f178c0ab47935ad8c561" + integrity sha512-uQwcd/tY+h1jnEaze6cdX/LrhWhoBxfSknxentoqmIuStxUExxjWd3ULMLFPiFUrZKbOVMowH6Jq2FRWfmhcEw== + +npm@~6.14.6: + version "6.14.18" + resolved "https://registry.yarnpkg.com/npm/-/npm-6.14.18.tgz#5cd431567f0961e1fe63d46738cf37f74f7999eb" + integrity sha512-p3SjqSchSuNQUqbJBgwdv0L3O6bKkaSfQrQzJsskNpNKLg0g37c5xTXFV0SqTlX9GWvoGxBELVJMRWq0J8oaLA== + dependencies: + JSONStream "^1.3.5" + abbrev "~1.1.1" + ansicolors "~0.3.2" + ansistyles "~0.1.3" + aproba "^2.0.0" + archy "~1.0.0" + bin-links "^1.1.8" + bluebird "^3.7.2" + byte-size "^5.0.1" + cacache "^12.0.4" + call-limit "^1.1.1" + chownr "^1.1.4" + ci-info "^2.0.0" + cli-columns "^3.1.2" + cli-table3 "^0.5.1" + cmd-shim "^3.0.3" + columnify "~1.5.4" + config-chain "^1.1.13" + detect-indent "~5.0.0" + detect-newline "^2.1.0" + dezalgo "^1.0.4" + editor "~1.0.0" + figgy-pudding "^3.5.2" + find-npm-prefix "^1.0.2" + fs-vacuum "~1.2.10" + fs-write-stream-atomic "~1.0.10" + gentle-fs "^2.3.1" + glob "^7.2.3" + graceful-fs "^4.2.10" + has-unicode "~2.0.1" + hosted-git-info "^2.8.9" + iferr "^1.0.2" + infer-owner "^1.0.4" + inflight "~1.0.6" + inherits "^2.0.4" + ini "^1.3.8" + init-package-json "^1.10.3" + is-cidr "^3.1.1" + json-parse-better-errors "^1.0.2" + lazy-property "~1.0.0" + libcipm "^4.0.8" + libnpm "^3.0.1" + libnpmaccess "^3.0.2" + libnpmhook "^5.0.3" + libnpmorg "^1.0.1" + libnpmsearch "^2.0.2" + libnpmteam "^1.0.2" + libnpx "^10.2.4" + lock-verify "^2.2.2" + lockfile "^1.0.4" + lodash._baseuniq "~4.6.0" + lodash.clonedeep "~4.5.0" + lodash.union "~4.6.0" + lodash.uniq "~4.5.0" + lodash.without "~4.4.0" + lru-cache "^5.1.1" + meant "^1.0.3" + mississippi "^3.0.0" + mkdirp "^0.5.6" + move-concurrently "^1.0.1" + node-gyp "^5.1.1" + nopt "^4.0.3" + normalize-package-data "^2.5.0" + npm-audit-report "^1.3.3" + npm-cache-filename "~1.0.2" + npm-install-checks "^3.0.2" + npm-lifecycle "^3.1.5" + npm-package-arg "^6.1.1" + npm-packlist "^1.4.8" + npm-pick-manifest "^3.0.2" + npm-profile "^4.0.4" + npm-registry-fetch "^4.0.7" + npm-user-validate "^1.0.1" + npmlog "~4.1.2" + once "~1.4.0" + opener "^1.5.2" + osenv "^0.1.5" + pacote "^9.5.12" + path-is-inside "~1.0.2" + promise-inflight "~1.0.1" + qrcode-terminal "^0.12.0" + query-string "^6.14.1" + qw "^1.0.2" + read "~1.0.7" + read-cmd-shim "^1.0.5" + read-installed "~4.0.3" + read-package-json "^2.1.2" + read-package-tree "^5.3.1" + readable-stream "^3.6.0" + readdir-scoped-modules "^1.1.0" + request "^2.88.2" + retry "^0.12.0" + rimraf "^2.7.1" + safe-buffer "^5.2.1" + semver "^5.7.1" + sha "^3.0.0" + slide "~1.1.6" + sorted-object "~2.0.1" + sorted-union-stream "~2.1.3" + ssri "^6.0.2" + stringify-package "^1.0.1" + tar "^4.4.19" + text-table "~0.2.0" + tiny-relative-date "^1.3.0" + uid-number "0.0.6" + umask "~1.1.0" + unique-filename "^1.1.1" + unpipe "~1.0.0" + update-notifier "^2.5.0" + uuid "^3.4.0" + validate-npm-package-license "^3.0.4" + validate-npm-package-name "~3.0.0" + which "^1.3.1" + worker-farm "^1.7.0" + write-file-atomic "^2.4.3" + +npmlog@^4.1.2, npmlog@~4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== @@ -20673,14 +21285,7 @@ npmlog@^6.0.0: gauge "^4.0.3" set-blocking "^2.0.0" -nth-check@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" - integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg== - dependencies: - boolbase "~1.0.0" - -nth-check@^2.0.0: +nth-check@^1.0.2, nth-check@^2.0.0, nth-check@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d" integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w== @@ -20715,11 +21320,6 @@ nwsapi@^2.2.0: resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== -oauth-sign@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.3.0.tgz#cb540f93bb2b22a7d5941691a288d60e8ea9386e" - integrity sha512-Tr31Sh5FnK9YKm7xTUPyDMsNOvMqkVDND0zvK/Wgj7/H9q8mpye0qG2nVzrnsvLhcsX5DtqXD0la0ks6rkPCGQ== - oauth-sign@~0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" @@ -20849,7 +21449,7 @@ on-headers@~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: +once@^1.3.0, once@^1.3.1, once@^1.4.0, once@~1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= @@ -20894,6 +21494,11 @@ open@^8.1.0: is-docker "^2.1.1" is-wsl "^2.2.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== + optionator@^0.8.1: version "0.8.3" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" @@ -20960,7 +21565,7 @@ os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.1, os-tmpdir@~1.0.2: resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= -osenv@^0.1.3, osenv@^0.1.4: +osenv@^0.1.3, osenv@^0.1.4, osenv@^0.1.5: version "0.1.5" resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== @@ -20980,11 +21585,6 @@ p-all@^2.1.0: dependencies: p-map "^2.0.0" -p-cancelable@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" - integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== - p-cancelable@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.1.tgz#aab7fbd416582fa32a3db49859c122487c5ed2cf" @@ -21142,6 +21742,16 @@ p-try@^2.0.0: resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== +package-json@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" + integrity sha512-q/R5GrMek0vzgoomq6rm9OX+3PQve8sLwTirmK30YB3Cu0Bbt9OX9M/SIUnroN5BGJkzwGsFwDaRGD9EwBOlCA== + dependencies: + got "^6.7.1" + registry-auth-token "^3.0.1" + registry-url "^3.0.3" + semver "^5.1.0" + package-json@^6.3.0: version "6.5.0" resolved "https://registry.yarnpkg.com/package-json/-/package-json-6.5.0.tgz#6feedaca35e75725876d0b0e64974697fed145b0" @@ -21152,6 +21762,42 @@ package-json@^6.3.0: registry-url "^5.0.0" semver "^6.2.0" +pacote@^9.1.0, pacote@^9.5.12, pacote@^9.5.3: + version "9.5.12" + resolved "https://registry.yarnpkg.com/pacote/-/pacote-9.5.12.tgz#1e11dd7a8d736bcc36b375a9804d41bb0377bf66" + integrity sha512-BUIj/4kKbwWg4RtnBncXPJd15piFSVNpTzY0rysSr3VnMowTYgkGKcaHrbReepAkjTr8lH2CVWRi58Spg2CicQ== + dependencies: + bluebird "^3.5.3" + cacache "^12.0.2" + chownr "^1.1.2" + figgy-pudding "^3.5.1" + get-stream "^4.1.0" + glob "^7.1.3" + infer-owner "^1.0.4" + lru-cache "^5.1.1" + make-fetch-happen "^5.0.0" + minimatch "^3.0.4" + minipass "^2.3.5" + mississippi "^3.0.0" + mkdirp "^0.5.1" + normalize-package-data "^2.4.0" + npm-normalize-package-bin "^1.0.0" + npm-package-arg "^6.1.0" + npm-packlist "^1.1.12" + npm-pick-manifest "^3.0.0" + npm-registry-fetch "^4.0.0" + osenv "^0.1.5" + promise-inflight "^1.0.1" + promise-retry "^1.1.1" + protoduck "^5.0.1" + rimraf "^2.6.2" + safe-buffer "^5.1.2" + semver "^5.6.0" + ssri "^6.0.1" + tar "^4.4.10" + unique-filename "^1.1.1" + which "^1.3.1" + pako@~1.0.5: version "1.0.11" resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" @@ -21291,11 +21937,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@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" @@ -21323,6 +21964,11 @@ path-is-absolute@1.0.1, path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= +path-is-inside@^1.0.1, path-is-inside@^1.0.2, path-is-inside@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + integrity sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w== + path-key@^2.0.0, path-key@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" @@ -21545,7 +22191,7 @@ playwright@^1.15.0: ws "^7.4.6" yazl "^2.5.1" -plist@^3.0.0, plist@^3.0.1, plist@^3.0.4: +plist@^3.0.0, plist@^3.0.1, plist@^3.0.4, plist@^3.0.5: version "3.0.6" resolved "https://registry.yarnpkg.com/plist/-/plist-3.0.6.tgz#7cfb68a856a7834bca6dbfe3218eb9c7740145d3" integrity sha512-WiIVYyrp8TD4w8yCvyeIr+lkmrGRd5u0VbRnU+tP/aRLxP/YadJUYOMZJ/6hIa3oUyVCsycXvtNRgd5XBJIbiA== @@ -21757,11 +22403,6 @@ prelude-ls@~1.1.2: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= -prepend-http@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" - integrity sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA== - pretender@^3.4.3, pretender@^3.4.7: version "3.4.7" resolved "https://registry.yarnpkg.com/pretender/-/pretender-3.4.7.tgz#34a2ae2d1fc9db440a990d50e6c0f5481d8755fc" @@ -21836,21 +22477,11 @@ printf@^0.6.1: resolved "https://registry.yarnpkg.com/printf/-/printf-0.6.1.tgz#b9afa3d3b55b7f2e8b1715272479fc756ed88650" integrity sha512-is0ctgGdPJ5951KulgfzvHGwJtZ5ck8l042vRkV6jrkpBzTmb/lueTqguWHy2JfVA+RY6gFVlaZgUS0j7S/dsw== -prismjs@^1.21.0, prismjs@^1.27.0: +prismjs@^1.21.0, prismjs@^1.27.0, prismjs@~1.24.0, prismjs@~1.27.0: version "1.29.0" resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.29.0.tgz#f113555a8fa9b57c35e637bba27509dcf802dd12" integrity sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q== -prismjs@~1.24.0: - version "1.24.1" - resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.24.1.tgz#c4d7895c4d6500289482fa8936d9cdd192684036" - integrity sha512-mNPsedLuk90RVJioIky8ANZEwYm5w9LcvCXrxHlwf4fNVSn8jEipMybMkWUyyF0JhnC+C4VcOVSBuHRKs1L5Ow== - -prismjs@~1.27.0: - version "1.27.0" - resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.27.0.tgz#bb6ee3138a0b438a3653dd4d6ce0cc6510a45057" - integrity sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA== - private@^0.1.8: version "0.1.8" resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" @@ -21891,7 +22522,7 @@ progress@^2.0.0, progress@^2.0.1, progress@^2.0.3: resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== -promise-inflight@^1.0.1: +promise-inflight@^1.0.1, promise-inflight@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= @@ -21908,6 +22539,14 @@ promise-map-series@^0.3.0: resolved "https://registry.yarnpkg.com/promise-map-series/-/promise-map-series-0.3.0.tgz#41873ca3652bb7a042b387d538552da9b576f8a1" integrity sha512-3npG2NGhTc8BWBolLLf8l/92OxMGaRLbqvIh9wjCHhDXNvk4zsxaTaCpiCunW09qWPrN2zeNSNwRLVBrQQtutA== +promise-retry@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-1.1.1.tgz#6739e968e3051da20ce6497fb2b50f6911df3d6d" + integrity sha512-StEy2osPr28o17bIW776GtwO6+Q+M9zPiZkYfosciUUMYqjhU/ffwRAH0zN2+uvGyUsn8/YICIHRzLbPacpZGw== + dependencies: + err-code "^1.0.0" + retry "^0.10.0" + promise-retry@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-2.0.1.tgz#ff747a13620ab57ba688f5fc67855410c370da22" @@ -21966,6 +22605,13 @@ prompts@^2.4.0: kleur "^3.0.3" sisteransi "^1.0.5" +promzard@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/promzard/-/promzard-0.3.0.tgz#26a5d6ee8c7dee4cb12208305acfb93ba382a9ee" + integrity sha512-JZeYqd7UAcHCwI+sTOeUDYkvEU+1bQ7iE0UT1MgB/tERkAPkesW46MrpIySzODi+owTjZtiF8Ay5j9m60KmMBw== + dependencies: + read "1" + prop-types@^15.0.0, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: version "15.7.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" @@ -21996,6 +22642,13 @@ proto-list@~1.2.1: resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk= +protoduck@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/protoduck/-/protoduck-5.0.1.tgz#03c3659ca18007b69a50fd82a7ebcc516261151f" + integrity sha512-WxoCeDCoCBY55BMvj4cAEjdVUFGRWed9ZxPlqTKYyw1nDDTQ4pqmnIMAGfJlg7Dx35uB/M+PHJPTmGOvaCaPTg== + dependencies: + genfun "^5.0.0" + proxy-addr@~2.0.7: version "2.0.7" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" @@ -22014,10 +22667,10 @@ prr@~1.0.1: resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= -psl@^1.1.28, 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== +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== public-encrypt@^4.0.0: version "4.0.3" @@ -22061,7 +22714,7 @@ punycode@1.3.2: resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= -punycode@^1.2.4: +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== @@ -22099,6 +22752,11 @@ q@^1.1.2: resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= +qrcode-terminal@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/qrcode-terminal/-/qrcode-terminal-0.12.0.tgz#bb5b699ef7f9f0505092a3748be4464fe71b5819" + integrity sha512-EXtzRZmC+YGmGlDFbXKxQiMZNwCLEO6BANKXG4iCtSIM0yqc/pappSx3RIKr4r0uh5JsBckOXeKrB3Iz7mdQpQ== + qs@6.11.0, qs@^6.10.0, qs@^6.4.0: version "6.11.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" @@ -22106,16 +22764,21 @@ qs@6.11.0, qs@^6.10.0, qs@^6.4.0: dependencies: side-channel "^1.0.4" -qs@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-1.0.2.tgz#50a93e2b5af6691c31bcea5dae78ee6ea1903768" - integrity sha512-tHuOP9TN/1VmDM/ylApGK1QF3PSIP8I6bHDEfoKNQeViREQ/sfu1bAUrA1hoDun8p8Tpm7jcsz47g+3PiGoYdg== - qs@~6.5.2: version "6.5.3" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad" integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA== +query-string@^6.14.1: + version "6.14.1" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.14.1.tgz#7ac2dca46da7f309449ba0f86b1fd28255b0c86a" + integrity sha512-XDxAeVmpfu1/6IjyT/gXHOl+S0vQ9owggJ30hhWKdHAsNPOcasn5o9BW0eejZqL2e4vMjhAxoW3jVHcD6mbcYw== + dependencies: + decode-uri-component "^0.2.0" + filter-obj "^1.1.0" + split-on-first "^1.0.0" + strict-uri-encode "^2.0.0" + querystring-es3@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" @@ -22131,11 +22794,6 @@ querystring@^0.2.0: 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== - queue-microtask@^1.2.2: version "1.2.3" resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" @@ -22179,6 +22837,11 @@ qunit@^2.17.2, qunit@^2.19.1: node-watch "0.7.3" tiny-glob "0.2.9" +qw@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/qw/-/qw-1.0.2.tgz#0c31a6f810320a91c58b05198679427103b03c4a" + integrity sha512-1PhZ/iLKwlVNq45dnerTMKFjMof49uqli7/0QsvPNbX5OJ3IZ8msa9lUpvPheVdP+IYYPrf6cOaVil7S35joVA== + ramda@^0.21.0: version "0.21.0" resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.21.0.tgz#a001abedb3ff61077d4ff1d577d44de77e8d0a35" @@ -22230,7 +22893,7 @@ raw-loader@^4.0.2: loader-utils "^2.0.0" schema-utils "^3.0.0" -rc@^1.2.8: +rc@^1.0.1, rc@^1.1.6, rc@^1.2.8: version "1.2.8" resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== @@ -22421,6 +23084,13 @@ react@16.14.0, react@^16: object-assign "^4.1.1" prop-types "^15.6.2" +read-cmd-shim@^1.0.1, read-cmd-shim@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/read-cmd-shim/-/read-cmd-shim-1.0.5.tgz#87e43eba50098ba5a32d0ceb583ab8e43b961c16" + integrity sha512-v5yCqQ/7okKoZZkBQUAfTsQ3sVJtXdNfbPnI5cceppoxEVLYA3k+VtV2omkeo8MS94JCy4fSiUwlRBAwCVRPUA== + dependencies: + graceful-fs "^4.1.2" + read-installed@~4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/read-installed/-/read-installed-4.0.3.tgz#ff9b8b67f187d1e4c29b9feb31f6b223acd19067" @@ -22435,7 +23105,7 @@ read-installed@~4.0.3: optionalDependencies: graceful-fs "^4.1.2" -read-package-json@^2.0.0: +"read-package-json@1 || 2", read-package-json@^2.0.0, read-package-json@^2.0.13, read-package-json@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-2.1.2.tgz#6992b2b66c7177259feb8eaac73c3acd28b9222a" integrity sha512-D1KmuLQr6ZSJS0tW8hf3WGpRlwszJOXZ3E8Yd/DNRaM5d+1wVRZdHlpGBLAuovjr28LbWvjpWkBHMxpRGGjzNA== @@ -22516,6 +23186,13 @@ read-pkg@^5.2.0: parse-json "^5.0.0" type-fest "^0.6.0" +read@1, read@~1.0.1, read@~1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4" + integrity sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ== + dependencies: + mute-stream "~0.0.4" + "readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, 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.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" @@ -22538,14 +23215,18 @@ read-pkg@^5.2.0: string_decoder "^1.1.1" util-deprecate "^1.0.1" -readable-stream@^3.4.0: - version "3.6.2" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" - integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== +readable-stream@^2.3.5: + version "2.3.8" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" + integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" + 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@~1.0.2: version "1.0.34" @@ -22557,7 +23238,7 @@ readable-stream@~1.0.2: isarray "0.0.1" string_decoder "~0.10.x" -readable-stream@~1.1.9: +readable-stream@~1.1.10, readable-stream@~1.1.9: version "1.1.14" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" integrity sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ== @@ -22567,7 +23248,7 @@ readable-stream@~1.1.9: isarray "0.0.1" string_decoder "~0.10.x" -readdir-scoped-modules@^1.0.0: +readdir-scoped-modules@^1.0.0, readdir-scoped-modules@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz#8d45407b4f870a0dcaebc0e28670d18e74514309" integrity sha512-asaikDeqAQg7JifRsZn1NJZXo9E+VwlyCfbkZhwyISinqk5zNS6266HS5kah6P0SaQKGF6SkNnZVHUzHFYxYDw== @@ -22780,6 +23461,14 @@ regexpu-core@^5.1.0: unicode-match-property-ecmascript "^2.0.0" unicode-match-property-value-ecmascript "^2.0.0" +registry-auth-token@^3.0.1: + version "3.4.0" + resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.4.0.tgz#d7446815433f5d5ed6431cd5dca21048f66b397e" + integrity sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A== + dependencies: + rc "^1.1.6" + safe-buffer "^5.0.1" + registry-auth-token@^4.0.0: version "4.2.1" resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-4.2.1.tgz#6d7b4006441918972ccd5fedcd41dc322c79b250" @@ -22787,6 +23476,13 @@ registry-auth-token@^4.0.0: dependencies: rc "^1.2.8" +registry-url@^3.0.3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942" + integrity sha512-ZbgR5aZEdf4UKZVBPYIgaglBmSF2Hi94s2PcIHhRGFjKYu+chjJdYfHn4rt3hB6eCKLJ8giVIIfgMa1ehDfZKA== + dependencies: + rc "^1.0.1" + registry-url@^5.0.0: version "5.1.0" resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-5.1.0.tgz#e98334b50d5434b81136b44ec638d9c2009c5009" @@ -22965,7 +23661,7 @@ repeating@^2.0.0: dependencies: is-finite "^1.0.0" -request@^2.45.0: +request@^2.45.0, request@^2.88.0, request@^2.88.2, request@~2.40.0: version "2.88.2" resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== @@ -22991,26 +23687,6 @@ request@^2.45.0: tunnel-agent "^0.6.0" uuid "^3.3.2" -request@~2.40.0: - version "2.40.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.40.0.tgz#4dd670f696f1e6e842e66b4b5e839301ab9beb67" - integrity sha512-waNoGB4Z7bPn+lgqPk7l7hhze4Vd68jKccnwLeS7vr9GMxz0iWQbYTbBNWzfIk87Urx7V44pu29qjF/omej+Fw== - dependencies: - forever-agent "~0.5.0" - json-stringify-safe "~5.0.0" - mime-types "~1.0.1" - node-uuid "~1.4.0" - qs "~1.0.0" - optionalDependencies: - aws-sign2 "~0.5.0" - form-data "~0.1.0" - hawk "1.1.1" - http-signature "~0.10.0" - oauth-sign "~0.3.0" - stringstream "~0.0.4" - tough-cookie ">=0.12.0" - tunnel-agent "~0.4.0" - require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" @@ -23021,6 +23697,11 @@ require-from-string@^2.0.2: resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== +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== + require-relative@^0.8.7: version "0.8.7" resolved "https://registry.yarnpkg.com/require-relative/-/require-relative-0.8.7.tgz#7999539fc9e047a37928fa196f8e1563dabd36de" @@ -23163,13 +23844,6 @@ resolve@^1.22.0, resolve@^1.22.1: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" -responselike@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" - integrity sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ== - dependencies: - lowercase-keys "^1.0.0" - responselike@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.0.tgz#26391bcc3174f750f9a79eacc40a12a5c42d7723" @@ -23198,6 +23872,11 @@ ret@~0.1.10: resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== +retry@^0.10.0: + version "0.10.1" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.10.1.tgz#e76388d217992c252750241d3d3956fed98d8ff4" + integrity sha512-ZXUSQYTHdl3uS7IuCehYfMzKyIDBNoAuUblvy5oGO5UJSUTmStUUVPXbA9Qxd173Bgre53yCQczQuHgRWAdvJQ== + retry@^0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" @@ -23213,7 +23892,7 @@ rfdc@^1.3.0: resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== -rimraf@^2.2.8, rimraf@^2.3.4, rimraf@^2.4.1, rimraf@^2.4.3, rimraf@^2.5.3, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@^2.6.3: +rimraf@^2.2.8, rimraf@^2.3.4, rimraf@^2.4.1, rimraf@^2.4.3, rimraf@^2.5.2, rimraf@^2.5.3, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@^2.6.3, rimraf@^2.7.1: version "2.7.1" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== @@ -23348,7 +24027,7 @@ safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: 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.1.0, 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.0: +safe-buffer@5.2.1, safe-buffer@>=5.1.0, 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== @@ -23504,6 +24183,13 @@ semver-compare@^1.0.0: resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w= +semver-diff@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" + integrity sha512-gL8F8L4ORwsS0+iQ34yCYv///jsOq0ZL7WP55d1HnJ32o7tyFYEFQZQA22mrLIacZdU6xecaBBZ+uEiffGNyXw== + dependencies: + semver "^5.0.3" + semver-diff@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-3.1.1.tgz#05f77ce59f325e00e2706afd67bb506ddb1ca32b" @@ -23511,7 +24197,7 @@ semver-diff@^3.1.1: dependencies: semver "^6.3.0" -"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.6.0: +"semver@2 || 3 || 4 || 5", "semver@2.x || 3.x || 4 || 5", "semver@^2.3.0 || 3.x || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0, semver@^5.7.1: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== @@ -23613,15 +24299,13 @@ set-blocking@^2.0.0, set-blocking@~2.0.0: resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= -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== +set-value@^2.0.0, set-value@^2.0.1, set-value@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-4.1.0.tgz#aa433662d87081b75ad88a4743bd450f044e7d09" + integrity sha512-zTEg4HL0RwVrqcWs3ztF+x1vkxfm0lP+MQQFPiMJTKVceBwEV0A569Ou8l9IYQG8jOZdMVI1hGsc0tmeD2o/Lw== dependencies: - extend-shallow "^2.0.1" - is-extendable "^0.1.1" - is-plain-object "^2.0.3" - split-string "^3.0.1" + is-plain-object "^2.0.4" + is-primitive "^3.0.1" setimmediate@^1.0.4, setimmediate@^1.0.5: version "1.0.5" @@ -23646,6 +24330,13 @@ sha.js@^2.4.0, sha.js@^2.4.8: inherits "^2.0.1" safe-buffer "^5.0.1" +sha@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/sha/-/sha-3.0.0.tgz#b2f2f90af690c16a3a839a6a6c680ea51fedd1ae" + integrity sha512-DOYnM37cNsLNSGIG/zZWch5CKIRNoLdYUQTQlcgkRkoYIUwDYjqDyye16YcDZg/OPdcbUgTKMjc4SY6TB7ZAPw== + dependencies: + graceful-fs "^4.1.2" + shallow-clone@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" @@ -23682,17 +24373,12 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -shell-quote@1.7.2: - version "1.7.2" - resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.2.tgz#67a7d02c76c9da24f99d20808fcaded0e0e04be2" - integrity sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg== - -shell-quote@^1.6.1: +shell-quote@1.7.2, shell-quote@^1.6.1, shell-quote@^1.7.3: version "1.8.0" resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.0.tgz#20d078d0eaf71d54f43bd2ba14a1b5b9bfa5c8ba" integrity sha512-QHsz8GgQIGKlRi24yFc6a6lN69Idnx634w49ay6+jA5yFh7a1UY+4Rp6HPx/L/1zcEDPEij8cIsiqR6bQsE5VQ== -shelljs@^0.8.4: +shelljs@^0.8.4, shelljs@^0.8.5: version "0.8.5" resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.5.tgz#de055408d8361bed66c669d2f000538ced8ee20c" integrity sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow== @@ -23807,12 +24493,12 @@ slice-ansi@^5.0.0: ansi-styles "^6.0.0" is-fullwidth-code-point "^4.0.0" -slide@~1.1.3: +slide@^1.1.6, slide@~1.1.3, slide@~1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" integrity sha1-VusCfWW00tzmyy4tMsTUr8nh1wc= -smart-buffer@^4.2.0: +smart-buffer@^4.1.0, smart-buffer@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== @@ -23855,13 +24541,6 @@ snapdragon@^0.8.1: source-map-resolve "^0.5.0" use "^3.1.0" -sntp@0.2.x: - version "0.2.4" - resolved "https://registry.yarnpkg.com/sntp/-/sntp-0.2.4.tgz#fb885f18b0f3aad189f824862536bceeec750900" - integrity sha512-bDLrKa/ywz65gCl+LmOiIhteP1bhEsAAzhfMedPoiHP3dyYnAevlaJshdqb9Yu0sRifyP/fRqSt8t+5qGIWlGQ== - dependencies: - hoek "0.9.x" - socket.io-adapter@~2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.4.0.tgz#b50a4a9ecdd00c34d4c8c808224daa1a786152a6" @@ -23887,6 +24566,23 @@ socket.io@^4.1.2: socket.io-adapter "~2.4.0" socket.io-parser "~4.2.1" +socks-proxy-agent@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-4.0.2.tgz#3c8991f3145b2799e70e11bd5fbc8b1963116386" + integrity sha512-NT6syHhI9LmuEMSK6Kd2V7gNv5KFZoLE7V5udWmn0de+3Mkj3UMA/AJPLyeNUVmElCurSHtUdM3ETpR3z770Wg== + dependencies: + agent-base "~4.2.1" + socks "~2.3.2" + +socks-proxy-agent@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-5.0.1.tgz#032fb583048a29ebffec2e6a73fca0761f48177e" + integrity sha512-vZdmnjb9a2Tz6WEQVIurybSwElwPxMZaIc7PzqbJTrezcKNznv6giT7J7tZDZ1BojVaa1jvO/UiUdhDVB0ACoQ== + dependencies: + agent-base "^6.0.2" + debug "4" + socks "^2.3.3" + socks-proxy-agent@^6.0.0: version "6.2.1" resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-6.2.1.tgz#2687a31f9d7185e38d530bef1944fe1f1496d6ce" @@ -23896,6 +24592,14 @@ socks-proxy-agent@^6.0.0: debug "^4.3.3" socks "^2.6.2" +socks@^2.3.3: + version "2.7.1" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.7.1.tgz#d8e651247178fde79c0663043e07240196857d55" + integrity sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ== + dependencies: + ip "^2.0.0" + smart-buffer "^4.2.0" + socks@^2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/socks/-/socks-2.6.2.tgz#ec042d7960073d40d94268ff3bb727dc685f111a" @@ -23904,6 +24608,14 @@ socks@^2.6.2: ip "^1.1.5" smart-buffer "^4.2.0" +socks@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.3.3.tgz#01129f0a5d534d2b897712ed8aceab7ee65d78e3" + integrity sha512-o5t52PCNtVdiOvzMry7wU4aOqYWL0PeCXRWBEiJow4/i/wr+wpsJQ9awEu1EonLIqsfGd5qSgDdxEOvCdmBEpA== + dependencies: + ip "1.1.5" + smart-buffer "^4.1.0" + solid-js@^1.3.0: version "1.6.11" resolved "https://registry.yarnpkg.com/solid-js/-/solid-js-1.6.11.tgz#263a512bf94efd89245a77f58dc18c195302237f" @@ -23928,6 +24640,19 @@ sort-package-json@^1.55.0, sort-package-json@^1.57.0: is-plain-obj "2.1.0" sort-object-keys "^1.1.3" +sorted-object@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/sorted-object/-/sorted-object-2.0.1.tgz#7d631f4bd3a798a24af1dffcfbfe83337a5df5fc" + integrity sha512-oKAAs26HeTu3qbawzUGCkTOBv/5MRrcuJyRWwbfEnWdpXnXsj+WEM3HTvarV73tMcf9uBEZNZoNDVRL62VLxzA== + +sorted-union-stream@~2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/sorted-union-stream/-/sorted-union-stream-2.1.3.tgz#c7794c7e077880052ff71a8d4a2dbb4a9a638ac7" + integrity sha512-RaKskQJZkmVREIwyAFho1RRU+sKjDdg51Crvxg2VxmIyiIrNhPNoJD/by5/pklWBXAZoO6LfAAGv8xd47p9TnQ== + dependencies: + from2 "^1.3.0" + stream-iterate "^1.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" @@ -23964,7 +24689,7 @@ source-map-support@^0.5.13, source-map-support@^0.5.16: buffer-from "^1.0.0" source-map "^0.6.0" -source-map-support@^0.5.6, source-map-support@~0.5.12, source-map-support@~0.5.20: +source-map-support@^0.5.6, source-map-support@~0.5.20: 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== @@ -23982,7 +24707,7 @@ source-map-url@^0.4.0: resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56" integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== -source-map@0.4.x, source-map@^0.4.2: +source-map@^0.4.2: version "0.4.4" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" integrity sha1-66T12pwNyZneaAMti092FzZSA2s= @@ -24090,7 +24815,12 @@ speedometer@~0.1.2: resolved "https://registry.yarnpkg.com/speedometer/-/speedometer-0.1.4.tgz#9876dbd2a169d3115402d48e6ea6329c8816a50d" integrity sha1-mHbb0qFp0xFUAtSObqYynIgWpQ0= -split-string@^3.0.1, split-string@^3.0.2: +split-on-first@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/split-on-first/-/split-on-first-1.1.0.tgz#f610afeee3b12bce1d0c30425e76398b78249a5f" + integrity sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw== + +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== @@ -24127,7 +24857,7 @@ sshpk@^1.7.0: safer-buffer "^2.0.2" tweetnacl "~0.14.0" -ssri@^6.0.1: +ssri@^6.0.0, ssri@^6.0.1, ssri@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.2.tgz#157939134f20464e7301ddba3e90ffa8f7728ac5" integrity sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q== @@ -24220,11 +24950,24 @@ stream-http@^2.7.2: to-arraybuffer "^1.0.0" xtend "^4.0.0" +stream-iterate@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/stream-iterate/-/stream-iterate-1.2.0.tgz#2bd7c77296c1702a46488b8ad41f79865eecd4e1" + integrity sha512-QVfGkdBQ8NzsSIiL3rV6AoFFWwMvlg1qpTwVQaMGY5XYThDUuNM4hYSzi8pbKlimTsWyQdaWRZE+jwlPsMiiZw== + dependencies: + readable-stream "^2.1.5" + stream-shift "^1.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== +strict-uri-encode@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546" + integrity sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ== + string-argv@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da" @@ -24252,7 +24995,7 @@ string-width@^1.0.1: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" -"string-width@^1.0.2 || 2", string-width@^2.1.0: +"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== @@ -24269,7 +25012,7 @@ string-width@^1.0.1: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -string-width@^3.0.0: +string-width@^3.0.0, string-width@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== @@ -24391,10 +25134,10 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -stringstream@~0.0.4: - version "0.0.6" - resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.6.tgz#7880225b0d4ad10e30927d167a1d6f2fd3b33a72" - integrity sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA== +stringify-package@^1.0.0, stringify-package@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/stringify-package/-/stringify-package-1.0.1.tgz#e5aa3643e7f74d0f28628b72f3dad5cecfc3ba85" + integrity sha512-sa4DUQsYciMP1xhKWGuFM04fB0LG/9DlluZoSVywUMRNvzid6XucHK0/90xGxRoHrAaROrcHK1aPKaijCtSrhg== strip-ansi@6.0.0, strip-ansi@^6.0.0: version "6.0.0" @@ -24417,7 +25160,7 @@ strip-ansi@^4.0.0: dependencies: ansi-regex "^3.0.0" -strip-ansi@^5.1.0, strip-ansi@^5.2.0: +strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== @@ -24872,7 +25615,7 @@ tapable@^2.1.1, tapable@^2.2.0: resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== -tar@^6.0.2, tar@^6.0.5, tar@^6.1.0, tar@^6.1.2: +tar@^4.4.10, tar@^4.4.12, tar@^4.4.19, tar@^6.0.2, tar@^6.0.5, tar@^6.1.0, tar@^6.1.2, tar@^6.1.9: version "6.1.13" resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.13.tgz#46e22529000f612180601a6fe0680e7da508847b" integrity sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw== @@ -24932,6 +25675,13 @@ temp@^0.8.1: dependencies: rimraf "~2.6.2" +term-size@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69" + integrity sha512-7dPUZQGy/+m3/wjVz3ZW5dobSoD/02NxJpoXUX0WIyjfVS3l0c+b/+9phIDFA7FHzkYtwtMFgeGZ/Y8jVTeqQQ== + dependencies: + execa "^0.7.0" + term-size@^2.1.0: version "2.2.1" resolved "https://registry.yarnpkg.com/term-size/-/term-size-2.2.1.tgz#2a6a54840432c2fb6320fea0f415531e90189f54" @@ -24987,19 +25737,10 @@ terser-webpack-plugin@^5.1.3: source-map "^0.6.1" terser "^5.7.2" -terser@^4.1.2, terser@^4.6.3: - 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" - -terser@^5.3.0, terser@^5.3.4, terser@^5.7.2: - version "5.16.6" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.16.6.tgz#f6c7a14a378ee0630fbe3ac8d1f41b4681109533" - integrity sha512-IBZ+ZQIA9sMaXmRZCUMDjNH0D5AQQfdn4WUjHL0+1lF4TP1IHRJbrhb6fNaXWikrYQTSkb7SLxkeXAiy1p7mbg== +terser@^4.1.2, terser@^4.6.3, terser@^5.14.2, terser@^5.3.0, terser@^5.3.4, terser@^5.7.2: + version "5.16.8" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.16.8.tgz#ccde583dabe71df3f4ed02b65eb6532e0fae15d5" + integrity sha512-QI5g1E/ef7d+PsDifb+a6nnVgC4F22Bg6T0xrBrz6iloVB4PUkkunp6V8nzoOOZJIzjWVdAGqCdlKlhLq/TbIA== dependencies: "@jridgewell/source-map" "^0.3.2" acorn "^8.5.0" @@ -25085,7 +25826,7 @@ testem@^3.8.0: tap-parser "^7.0.0" tmp "0.0.33" -text-table@0.2.0, text-table@^0.2.0: +text-table@0.2.0, text-table@^0.2.0, text-table@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== @@ -25134,7 +25875,7 @@ through2@~0.2.3: readable-stream "~1.1.9" xtend "~2.1.1" -through@^2.3.6, through@^2.3.8: +"through@>=2.2.7 <3", through@^2.3.6, 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== @@ -25176,6 +25917,11 @@ tiny-lr@^2.0.0: object-assign "^4.1.0" qs "^6.4.0" +tiny-relative-date@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/tiny-relative-date/-/tiny-relative-date-1.3.0.tgz#fa08aad501ed730f31cc043181d995c39a935e07" + integrity sha512-MOQHpzllWxDCHHaDno30hhLfbouoYlOI8YlMNtvKe1zXbjEVhbcEovQxvZrPvtiYW630GQDoMMarCnjfyfHA+A== + tmp@0.0.28: version "0.0.28" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.28.tgz#172735b7f614ea7af39664fa84cf0de4e515d120" @@ -25204,7 +25950,7 @@ tmp@^0.2.1: dependencies: rimraf "^3.0.0" -tmpl@1.0.x: +tmpl@1.0.x, tmpl@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== @@ -25231,11 +25977,6 @@ to-object-path@^0.3.0: dependencies: kind-of "^3.0.2" -to-readable-stream@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771" - integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q== - 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" @@ -25271,23 +26012,12 @@ toidentifier@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@>=0.12.0, tough-cookie@^4.0.0: - version "4.1.2" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.2.tgz#e53e84b85f24e0b65dd526f46628db6c85f6b874" - integrity sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ== +tough-cookie@^4.0.0, tough-cookie@~2.3.3, tough-cookie@~2.5.0: + version "2.3.4" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.4.tgz#ec60cee38ac675063ffc97a5c18970578ee83655" + integrity sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA== dependencies: - psl "^1.1.33" - punycode "^2.1.1" - universalify "^0.2.0" - url-parse "^1.5.3" - -tough-cookie@~2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" - integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== - dependencies: - psl "^1.1.28" - punycode "^2.1.1" + punycode "^1.4.1" tr46@^2.1.0: version "2.1.0" @@ -25338,12 +26068,7 @@ treeify@^1.1.0: resolved "https://registry.yarnpkg.com/treeify/-/treeify-1.1.0.tgz#4e31c6a463accd0943879f30667c4fdaff411bb8" integrity sha512-1m4RA7xVAJrSGrrXGs0L3YTwyvBs2S8PbRHaLZAkFw7JR8oIFwYtysxlBZhYIa7xSyiYJKZ3iGrrk55cGA3i9A== -trim-newlines@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" - integrity sha512-Nm4cF79FhSTzrLKGDMi3I4utBtFv8qKy4sq1enftf2gMdpqI8oVQTAfySkTz5r49giVzDj88SVZXP4CeYQwjaw== - -trim-newlines@^3.0.0: +trim-newlines@^1.0.0, trim-newlines@^3.0.0, trim-newlines@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-3.0.1.tgz#260a5d962d8b752425b32f3a7db0dcacd176c144" integrity sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw== @@ -25365,10 +26090,10 @@ trim-trailing-lines@^1.0.0: resolved "https://registry.yarnpkg.com/trim-trailing-lines/-/trim-trailing-lines-1.1.4.tgz#bd4abbec7cc880462f10b2c8b5ce1d8d1ec7c2c0" integrity sha512-rjUWSqnfTNrjbB9NQWfPMH/xRK1deHeGsHoVfpxJ++XeYXE0d6B1En37AHfw3jtfTU7dzMzZL2jjpe8Qb5gLIQ== -trim@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/trim/-/trim-0.0.1.tgz#5858547f6b290757ee95cccc666fb50084c460dd" - integrity sha512-YzQV+TZg4AxpKxaTHK3c3D+kRDCGVEE7LemdlQZoQXn0iennk10RsIoY6ikzAqJTc9Xjl9C1/waHom/J86ziAQ== +trim@0.0.1, trim@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim/-/trim-1.0.1.tgz#68e78f6178ccab9687a610752f4f5e5a7022ee8c" + integrity sha512-3JVP2YVqITUisXblCDq/Bi4P9457G/sdEamInkyvCsjbTcXLXIiG7XCb4kGMFWh6JGXesS3TKxOPtrncN/xe8w== trough@^1.0.0: version "1.0.5" @@ -25422,18 +26147,13 @@ tty-browserify@0.0.0: resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY= -tunnel-agent@^0.6.0: +tunnel-agent@^0.6.0, 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" -tunnel-agent@~0.4.0: - version "0.4.3" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.4.3.tgz#6373db76909fe570e08d73583365ed828a74eeeb" - integrity sha512-e0IoVDWx8SDHc/hwFTqJDQ7CCDTEeGhmcT9jkWJjoGQSpgBz20nAMr80E3Tpk7PatJ1b37DQDgJR3CNSzcMOZQ== - tunnel@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c" @@ -25543,7 +26263,7 @@ typescript@~4.2.4: resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.4.tgz#8610b59747de028fda898a8aef0e103f156d0961" integrity sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg== -uc.micro@^1.0.0, uc.micro@^1.0.1, uc.micro@^1.0.5: +uc.micro@^1.0.1, uc.micro@^1.0.5: version "1.0.6" resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac" integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA== @@ -25553,6 +26273,16 @@ uglify-js@^3.1.4: resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.14.1.tgz#e2cb9fe34db9cb4cf7e35d1d26dfea28e09a7d06" integrity sha512-JhS3hmcVaXlp/xSo3PKY5R0JqKs5M3IV+exdLHW99qKvKivPO4Z8qbej6mte17SOPqAOVMjt/XGgWacnFSzM3g== +uid-number@0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" + integrity sha512-c461FXIljswCuscZn67xq9PpszkPT6RjheWFQTgCyabJrTUozElanb0YEqv2UGgk247YpcJkFBuSGNvBlpXM9w== + +umask@^1.1.0, umask@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/umask/-/umask-1.1.0.tgz#f29cebf01df517912bb58ff9c4e50fde8e33320d" + integrity sha512-lE/rxOhmiScJu9L6RTNVgB/zZbF+vGC0/p6D3xnkAePI2o0sMyFG966iR5Ki50OI/0mNi2yaRnxfLsPmEZF/JA== + unbox-primitive@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" @@ -25571,16 +26301,11 @@ underscore.string@^3.2.2, underscore.string@~3.3.4: sprintf-js "^1.0.3" util-deprecate "^1.0.2" -underscore@>=1.8.3, underscore@^1.13.2: +underscore@>=1.8.3, underscore@^1.12.1, underscore@^1.13.2, underscore@~1.6.0: version "1.13.6" resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.6.tgz#04786a1f589dc6c09f761fc5f45b89e935136441" integrity sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A== -underscore@~1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.6.0.tgz#8b38b10cacdef63337b8b24e4ff86d45aea529a8" - integrity sha512-z4o1fvKUojIWh9XuaVLUDdf86RQiq13AC1dmHbTpoyuu+bquHms76v16CjycCbec87J7z0k//SiQVk0sMdFmpQ== - unfetch@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/unfetch/-/unfetch-4.2.0.tgz#7e21b0ef7d363d8d9af0fb929a5555f6ef97a3be" @@ -25688,6 +26413,13 @@ unique-slug@^2.0.0: dependencies: imurmurhash "^0.1.4" +unique-string@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-1.0.0.tgz#9e1057cca851abb93398f8b33ae187b99caec11a" + integrity sha512-ODgiYu03y5g76A1I9Gt0/chLCzQjvzDy7DsZGsLOE/1MrF6wriEskSncj1+/C58Xk/kPZDppSctDybCwOSaGAg== + dependencies: + crypto-random-string "^1.0.0" + unique-string@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d" @@ -25758,11 +26490,6 @@ universalify@^0.1.0: 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.0" resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" @@ -25811,6 +26538,22 @@ update-browserslist-db@^1.0.10: escalade "^3.1.1" picocolors "^1.0.0" +update-notifier@^2.3.0, update-notifier@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-2.5.0.tgz#d0744593e13f161e406acb1d9408b72cad08aff6" + integrity sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw== + dependencies: + boxen "^1.2.1" + chalk "^2.0.1" + configstore "^3.0.0" + import-lazy "^2.1.0" + is-ci "^1.0.10" + is-installed-globally "^0.1.0" + is-npm "^1.0.0" + latest-version "^3.0.0" + semver-diff "^2.0.0" + xdg-basedir "^3.0.0" + update-notifier@^5.0.1: version "5.1.0" resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-5.1.0.tgz#4ab0d7c7f36a231dd7316cf7729313f0214d9ad9" @@ -25857,21 +26600,6 @@ url-loader@^4.1.1: mime-types "^2.1.27" schema-utils "^3.0.0" -url-parse-lax@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" - integrity sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ== - dependencies: - prepend-http "^2.0.0" - -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.0" resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" @@ -25981,12 +26709,12 @@ uuid-browser@^3.1.0: resolved "https://registry.yarnpkg.com/uuid-browser/-/uuid-browser-3.1.0.tgz#0f05a40aef74f9e5951e20efbf44b11871e56410" integrity sha1-DwWkCu90+eWVHiDvv0SxGHHlZBA= -uuid@^3.3.2: +uuid@^3.3.2, uuid@^3.4.0: version "3.4.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== -uuid@^8.3.2: +uuid@^8.3.0, 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== @@ -26005,7 +26733,7 @@ v8-to-istanbul@^8.1.0: convert-source-map "^1.6.0" source-map "^0.7.3" -validate-npm-package-license@^3.0.1: +validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== @@ -26013,7 +26741,7 @@ validate-npm-package-license@^3.0.1: spdx-correct "^3.0.0" spdx-expression-parse "^3.0.0" -validate-npm-package-name@^3.0.0: +validate-npm-package-name@^3.0.0, validate-npm-package-name@~3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz#5fa912d81eb7d0c74afc140de7317f0ca7df437e" integrity sha1-X6kS2B630MdK/BQN5zF/DKffQ34= @@ -26228,7 +26956,7 @@ watchpack@^2.3.1, watchpack@^2.4.0: glob-to-regexp "^0.4.1" graceful-fs "^4.1.2" -wcwidth@^1.0.1: +wcwidth@^1.0.0, wcwidth@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" integrity sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg== @@ -26492,7 +27220,12 @@ which-boxed-primitive@^1.0.2: is-string "^1.0.5" is-symbol "^1.0.3" -which@^1.2.14, which@^1.2.9, which@^1.3.1: +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + integrity sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q== + +which@^1.2.14, which@^1.2.9, which@^1.3.0, which@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== @@ -26520,6 +27253,13 @@ wide-align@^1.1.2, wide-align@^1.1.5: dependencies: string-width "^1.0.2 || 2 || 3 || 4" +widest-line@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-2.0.1.tgz#7438764730ec7ef4381ce4df82fb98a53142a3fc" + integrity sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA== + dependencies: + string-width "^2.1.1" + widest-line@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca" @@ -26554,7 +27294,7 @@ wordwrap@^1.0.0: resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= -worker-farm@^1.7.0: +worker-farm@^1.6.0, 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== @@ -26582,7 +27322,7 @@ workerpool@^6.0.0: resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.1.5.tgz#0f7cf076b6215fd7e1da903ff6f22ddd1886b581" integrity sha512-XdKkCK0Zqc6w3iTxLckiuJ81tiD/o5rBE/m+nXpRCB+/Sq4DqkfXZ/x0jW02DG1tGsfUGXbTJyZDP+eu67haSw== -workerpool@^6.1.5, workerpool@^6.2.0: +workerpool@^6.2.0: version "6.2.1" resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== @@ -26592,6 +27332,20 @@ workerpool@^6.2.1: resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.3.1.tgz#80a9b76e70556acfb1457a3984f8637717f7cdee" integrity sha512-0x7gJm1rhpn5SPG9NENOxPtbfUZZtK/qOg6gEdSqeDBA3dTeR91RJqSPjccPRCkhNfrnnl/dWxSSj5w9CtdzNA== +workerpool@^6.4.0: + version "6.4.0" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.4.0.tgz#f8d5cfb45fde32fa3b7af72ad617c3369567a462" + integrity sha512-i3KR1mQMNwY2wx20ozq2EjISGtQWDIfV56We+yGJ5yDs8jTwQiLLaqHlkBHITlCuJnYlVRmXegxFxZg7gqI++A== + +wrap-ansi@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" + integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== + dependencies: + ansi-styles "^3.2.0" + string-width "^3.0.0" + strip-ansi "^5.0.0" + wrap-ansi@^6.2.0: version "6.2.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" @@ -26625,7 +27379,7 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= -write-file-atomic@^2.3.0: +write-file-atomic@^2.0.0, write-file-atomic@^2.3.0, write-file-atomic@^2.4.3: version "2.4.3" resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.3.tgz#1fd2e9ae1df3e75b8d8c367443c692d4ca81f481" integrity sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ== @@ -26652,22 +27406,15 @@ write-file-atomic@^4.0.2: imurmurhash "^0.1.4" signal-exit "^3.0.7" -ws@^6.1.0: - version "6.2.2" - resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.2.tgz#dd5cdbd57a9979916097652d78f1cc5faea0c32e" - integrity sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw== - dependencies: - async-limiter "~1.0.0" - -ws@^7.4.6: +ws@^6.1.0, ws@^7.4.6, ws@~8.2.3: version "7.5.3" resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.3.tgz#160835b63c7d97bfab418fc1b8a9fced2ac01a74" integrity sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg== -ws@~8.2.3: - version "8.2.3" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.2.3.tgz#63a56456db1b04367d0b721a0b80cae6d8becbba" - integrity sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA== +xdg-basedir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" + integrity sha512-1Dly4xqlulvPD3fZUQJLY+FUIeqN3N2MM3uqe4rCJftAvOjFa3jFGfctOgluGx4ahPbUCsZkmJILiP0Vi4T6lQ== xdg-basedir@^4.0.0: version "4.0.0" @@ -26689,6 +27436,11 @@ xmlchars@^2.2.0: resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== +xmlhttprequest-ssl@^1.6.2: + version "1.6.3" + resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.6.3.tgz#03b713873b01659dfa2c1c5d056065b27ddc2de6" + integrity sha512-3XfeQE/wNkvrIktn2Kf0869fC0BN6UpydVasGIeSm2B1Llihf7/0UfZM+eCkOw3P7bP4+qPgqhm7ZoxuJtFU0Q== + xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" @@ -26711,6 +27463,11 @@ y18n@^5.0.5: 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.0, yallist@^3.0.2: version "3.1.1" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" @@ -26739,15 +27496,27 @@ yaml@^2.1.1: resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.1.1.tgz#1e06fb4ca46e60d9da07e4f786ea370ed3c3cfec" integrity sha512-o96x3OPo8GjWeSLF+wOAbrPfhFOGY0W00GNaxCDv+9hkcDJEnev1yh8S7pgHF0ik6zc8sQLuL8hjHjJULZp8bw== -yargs-parser@^20.0.0, yargs-parser@^20.2.2, yargs-parser@^20.2.3: +yargs-parser@^15.0.1, yargs-parser@^20.0.0, yargs-parser@^20.2.2, yargs-parser@^20.2.3, yargs-parser@^21.0.0, yargs-parser@~20.2.7: version "20.2.9" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== -yargs-parser@^21.0.0: - version "21.1.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" - integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== +yargs@^14.2.3: + version "14.2.3" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-14.2.3.tgz#1a1c3edced1afb2a2fea33604bc6d1d8d688a414" + integrity sha512-ZbotRWhF+lkjijC/VhmOT9wSgyBQ7+zr13+YLkhfsSiTriYsMzkTUFP18pFhWwBeMa5gUc1MzbhrO6/VB7c9Xg== + dependencies: + cliui "^5.0.0" + decamelize "^1.2.0" + find-up "^3.0.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 "^3.0.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^15.0.1" yargs@^16.2.0: version "16.2.0" From 811025bccbb78d0cf1ee913298b3acc1ed98c566 Mon Sep 17 00:00:00 2001 From: Zhihe Li Date: Mon, 3 Apr 2023 11:56:05 -0400 Subject: [PATCH 108/193] =?UTF-8?q?refactor:=20=F0=9F=92=A1=20Remove=20ses?= =?UTF-8?q?sion=20recording=20type=20check=20and=20update=20name=20(#179)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/addon/abilities/channel-recording.js | 2 +- .../api/addon/abilities/session-recording.js | 2 +- .../unit/abilities/channel-recording-test.js | 10 +---- .../unit/abilities/session-recording-test.js | 37 +------------------ 4 files changed, 5 insertions(+), 46 deletions(-) diff --git a/addons/api/addon/abilities/channel-recording.js b/addons/api/addon/abilities/channel-recording.js index fb6676466..54164b881 100644 --- a/addons/api/addon/abilities/channel-recording.js +++ b/addons/api/addon/abilities/channel-recording.js @@ -14,7 +14,7 @@ export default class ChannelRecordingAbility extends ModelAbility { @service abilities; // =permissions - get canDownloadAsciicast() { + get canGetAsciicast() { const sessionRecording = this.model.connection_recording.session_recording; const sessionRecordingAbility = this.abilities.abilityFor( 'session-recording', diff --git a/addons/api/addon/abilities/session-recording.js b/addons/api/addon/abilities/session-recording.js index 1e6360092..13d2fc4bb 100644 --- a/addons/api/addon/abilities/session-recording.js +++ b/addons/api/addon/abilities/session-recording.js @@ -29,6 +29,6 @@ export default class SessionRecordingAbility extends ModelAbility { } get canDownload() { - return this.model.isSSH && this.hasAuthorizedAction('download'); + return this.hasAuthorizedAction('download'); } } diff --git a/addons/api/tests/unit/abilities/channel-recording-test.js b/addons/api/tests/unit/abilities/channel-recording-test.js index dff28858d..335d85d9d 100644 --- a/addons/api/tests/unit/abilities/channel-recording-test.js +++ b/addons/api/tests/unit/abilities/channel-recording-test.js @@ -38,10 +38,7 @@ module('Unit | Ability | channel-recording', function (hooks) { }); assert.true( - canService.can( - 'downloadAsciicast channel-recording', - channelRecordingModel - ) + canService.can('getAsciicast channel-recording', channelRecordingModel) ); }); @@ -64,10 +61,7 @@ module('Unit | Ability | channel-recording', function (hooks) { }); assert.false( - canService.can( - 'downloadAsciicast channel-recording', - channelRecordingModel - ) + canService.can('getAsciicast channel-recording', channelRecordingModel) ); }); }); diff --git a/addons/api/tests/unit/abilities/session-recording-test.js b/addons/api/tests/unit/abilities/session-recording-test.js index 729aebd07..5e258a323 100644 --- a/addons/api/tests/unit/abilities/session-recording-test.js +++ b/addons/api/tests/unit/abilities/session-recording-test.js @@ -1,6 +1,5 @@ import { module, test } from 'qunit'; import { setupTest } from 'ember-qunit'; -import { TYPE_SESSION_RECORDING_SSH } from 'api/models/session-recording'; module('Unit | Ability | session-recording', function (hooks) { setupTest(hooks); @@ -18,21 +17,19 @@ module('Unit | Ability | session-recording', function (hooks) { assert.ok(ability); }); - test('can download when an ssh recording has download authorization', function (assert) { + test('can download when a recording has download authorization', function (assert) { assert.expect(2); const recordingWithAuthorizedAction = store.createRecord( 'session-recording', { authorized_actions: ['download'], - type: TYPE_SESSION_RECORDING_SSH, } ); const recordingWithoutAuthorizedAction = store.createRecord( 'session-recording', { authorized_actions: [], - type: TYPE_SESSION_RECORDING_SSH, } ); @@ -49,36 +46,4 @@ module('Unit | Ability | session-recording', function (hooks) { ) ); }); - - test('cannot download when a recording is not ssh type', function (assert) { - assert.expect(2); - - const recordingWithAuthorizedAction = store.createRecord( - 'session-recording', - { - authorized_actions: ['download'], - type: 'unknown', - } - ); - const recordingWithoutAuthorizedAction = store.createRecord( - 'session-recording', - { - authorized_actions: [], - type: 'unknown', - } - ); - - assert.false( - canService.can( - 'download session-recording', - recordingWithAuthorizedAction - ) - ); - assert.false( - canService.can( - 'download session-recording', - recordingWithoutAuthorizedAction - ) - ); - }); }); From 7080b07ab377d830fac24c1d3aba645ba636e006 Mon Sep 17 00:00:00 2001 From: lisbet-alvarez <107949262+lisbet-alvarez@users.noreply.github.com> Date: Mon, 3 Apr 2023 18:12:44 -0700 Subject: [PATCH 109/193] Link list panel component (#182) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: πŸ€– update parent branch * chore: πŸ€– fix merge conflict * chore: πŸ€– merge conflict * refactor: πŸ’‘ merge conflict * chore: πŸ€– update branch * fix: πŸ› translation * refactor: πŸ’‘ use
    &
  • and make entire row a link --- addons/core/translations/resources/en-us.yaml | 2 ++ .../app/components/link-list-panel/index.hbs | 16 ++++++++++ .../components/link-list-panel/item/index.hbs | 16 ++++++++++ ui/admin/app/styles/app.scss | 30 +++++++++++++++++++ .../scopes/scope/targets/target/index.hbs | 27 +++++++++++++---- .../components/link-list-panel/index-test.js | 28 +++++++++++++++++ 6 files changed, 114 insertions(+), 5 deletions(-) create mode 100644 ui/admin/app/components/link-list-panel/index.hbs create mode 100644 ui/admin/app/components/link-list-panel/item/index.hbs create mode 100644 ui/admin/tests/integration/components/link-list-panel/index-test.js diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml index 680e5c0fa..a96c0e70f 100644 --- a/addons/core/translations/resources/en-us.yaml +++ b/addons/core/translations/resources/en-us.yaml @@ -261,6 +261,8 @@ storage-bucket: aws: AWS global: Global orgs: Orgs + types: + aws_s3: AWS S3 actions: delete: Delete Storage Bucket form: diff --git a/ui/admin/app/components/link-list-panel/index.hbs b/ui/admin/app/components/link-list-panel/index.hbs new file mode 100644 index 000000000..4ac7f4064 --- /dev/null +++ b/ui/admin/app/components/link-list-panel/index.hbs @@ -0,0 +1,16 @@ + +
      + {{yield + (hash + Item=(component + 'link-list-panel/item' + icon=@icon + color=@color + text=@text + route=@route + model=@model + ) + ) + }} +
    +
    \ No newline at end of file diff --git a/ui/admin/app/components/link-list-panel/item/index.hbs b/ui/admin/app/components/link-list-panel/item/index.hbs new file mode 100644 index 000000000..898cf91e3 --- /dev/null +++ b/ui/admin/app/components/link-list-panel/item/index.hbs @@ -0,0 +1,16 @@ +
  • + + + {{#if @route}} + + {{/if}} + +
  • \ No newline at end of file diff --git a/ui/admin/app/styles/app.scss b/ui/admin/app/styles/app.scss index 99cf43f94..f2dba4b71 100644 --- a/ui/admin/app/styles/app.scss +++ b/ui/admin/app/styles/app.scss @@ -679,6 +679,36 @@ } } +.link-list-item { + display: flex; + align-items: center; + justify-content: space-between; + padding: 1rem; + text-decoration: none; + + &__info { + display: flex; + align-items: center; + gap: 0.75rem; + margin-left: 0.25rem; + } + + &__text { + color: var(--token-color-foreground-primary); + margin-bottom: 0.25rem; + } + + .flight-icon-chevron-right { + color: var(--token-color-foreground-faint); + } + + .hds-button { + box-shadow: none; + border: none; + background-color: transparent; + } +} + .key-value-list { border: 0; diff --git a/ui/admin/app/templates/scopes/scope/targets/target/index.hbs b/ui/admin/app/templates/scopes/scope/targets/target/index.hbs index f0ce80553..212d49bbc 100644 --- a/ui/admin/app/templates/scopes/scope/targets/target/index.hbs +++ b/ui/admin/app/templates/scopes/scope/targets/target/index.hbs @@ -47,11 +47,28 @@

    {{t 'resources.target.form.sidebar.help'}}

    - + {{#if @model.storage_bucket_id}} + + + + + + {{else}} + + {{/if}}
{{/if}} diff --git a/ui/admin/tests/integration/components/link-list-panel/index-test.js b/ui/admin/tests/integration/components/link-list-panel/index-test.js new file mode 100644 index 000000000..dfaf42d10 --- /dev/null +++ b/ui/admin/tests/integration/components/link-list-panel/index-test.js @@ -0,0 +1,28 @@ +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'admin/tests/helpers'; +import { render } from '@ember/test-helpers'; +import { hbs } from 'ember-cli-htmlbars'; + +module('Integration | Component | link-list-panel/index', function (hooks) { + setupRenderingTest(hooks); + + test('it renders with icons and text', async function (assert) { + assert.expect(5); + await render(hbs` + + + + + + `); + + assert.dom('[data-test-icon="cloud-upload"]').isVisible(); + assert.dom('[data-test-icon="chevron-right"]').isVisible(); + assert.dom('[data-test-icon="aws-color"]').isVisible(); + assert.dom('.hds-badge__text').hasText('AWS S3'); + assert.dom('.link-list-item__text').hasText('Storage Bucket'); + }); +}); From 2a9c4507d200512308bb6fc96da7271c2eda58aa Mon Sep 17 00:00:00 2001 From: Randall Morey Date: Mon, 3 Apr 2023 20:28:31 -0700 Subject: [PATCH 110/193] Main to session recording (#178) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: πŸ› add model hook to host route for dynamic host catalogs (#1659) * fix: πŸ› add model hook to host route for dynamic host catalogs βœ… Closes: ICU-8594 * refactor: πŸ’‘ remove page formatting for host route * [COMPLIANCE] Add Copyright and License Headers (#1660) Co-authored-by: hashicorp-copywrite[bot] <110428419+hashicorp-copywrite[bot]@users.noreply.github.com> Co-authored-by: Carlos Alcaide Corvo * chore(deps-dev): bump webpack from 5.59.1 to 5.76.0 (#1654) Bumps [webpack](https://github.com/webpack/webpack) from 5.59.1 to 5.76.0. - [Release notes](https://github.com/webpack/webpack/releases) - [Commits](https://github.com/webpack/webpack/compare/v5.59.1...v5.76.0) --- updated-dependencies: - dependency-name: webpack dependency-type: direct:development ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Randall Morey Co-authored-by: Carlos Alcaide Corvo * Feature metadata (#1661) * feat: 🎸 load edition from controller-metadata.json * refactor: πŸ’‘ rename edition and add licensed features support * chore: πŸ€– support dev toggling of licensed features * chore: πŸ€– rename ent edition * Update ui/admin/app/services/feature-edition.js * Update ui/admin/app/instance-initializers/feature-edition.js Co-authored-by: Zhihe Li * chore: πŸ€– cleanup * chore: πŸ€– feature edition disabled in tests / fix test cases * test: πŸ’ remove feature disable calls in tests * test: πŸ’ fix broken tests * fix: πŸ› fix config bug * fix: πŸ› fix broken test due to feature flags --------- Co-authored-by: Zhihe Li * chore: πŸ€– yarn.lock update * fix: πŸ› fix test features --------- Signed-off-by: dependabot[bot] Co-authored-by: lisbet-alvarez <107949262+lisbet-alvarez@users.noreply.github.com> Co-authored-by: hashicorp-copywrite[bot] <110428419+hashicorp-copywrite[bot]@users.noreply.github.com> Co-authored-by: Carlos Alcaide Corvo Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Zhihe Li Co-authored-by: github-team-secure-boundary Co-authored-by: hc-github-team-secure-boundary <82989682+hc-github-team-secure-boundary@users.noreply.github.com> --- addons/api/mirage/config.js | 15 ++ addons/api/package.json | 2 +- addons/auth/package.json | 2 +- addons/core/package.json | 2 +- addons/core/translations/actions/en-us.yaml | 1 + addons/core/translations/en-us.yaml | 5 - addons/rose/package.json | 2 +- .../instance-initializers/feature-edition.js | 37 ++- ui/admin/app/routes/application.js | 10 + .../host-sets/host-set/hosts/host.js | 19 +- ui/admin/app/services/feature-edition.js | 31 ++- ui/admin/app/templates/application.hbs | 18 +- .../host-catalog/hosts/host/index.hbs | 2 +- ui/admin/config/environment.js | 48 ++-- ui/admin/config/features.js | 32 +-- ui/admin/package.json | 2 +- .../credential-library/create-test.js | 10 +- .../credential-library/read-test.js | 7 +- .../credential-store/create-test.js | 4 + .../credentials/create-test.js | 10 +- .../credential-store/credentials/read-test.js | 9 +- .../acceptance/credential-store/read-test.js | 5 + ui/admin/tests/acceptance/develop-test.js | 7 + .../session-recordings/read-test.js | 12 +- .../acceptance/storage-buckets/list-test.js | 23 +- .../brokered-credential-sources-test.js | 5 +- .../tests/acceptance/targets/create-test.js | 51 +++-- .../tests/acceptance/targets/read-test.js | 16 +- .../tests/acceptance/targets/update-test.js | 10 +- .../tests/acceptance/workers/create-test.js | 8 +- .../tests/acceptance/workers/list-test.js | 8 +- .../dual-filter/hcp/index-test.js | 2 - .../worker-diagram/dual-filter/index-test.js | 2 - .../components/worker-diagram/index-test.js | 19 +- .../unit/abilities/credential-library-test.js | 11 +- .../tests/unit/abilities/credential-test.js | 16 +- .../feature-edition-test.js | 5 + .../unit/services/feature-edition-test.js | 5 + ui/desktop/package.json | 2 +- yarn.lock | 211 ++---------------- 40 files changed, 351 insertions(+), 335 deletions(-) mode change 100755 => 100644 ui/desktop/package.json diff --git a/addons/api/mirage/config.js b/addons/api/mirage/config.js index a5b9a1e7d..8a42d9662 100644 --- a/addons/api/mirage/config.js +++ b/addons/api/mirage/config.js @@ -38,6 +38,21 @@ function routes() { this.passthrough(); // make this `http://localhost:8080`, for example, if your API is on a different server // this.urlPrefix = ''; + + this.get('/metadata.json', () => { + // this configuration is optional + const licensedFeatures = environmentConfig?.features?.licensedFeatures; + const edition = licensedFeatures ? 'enterprise' : 'oss'; + const features = licensedFeatures ? Object.keys(licensedFeatures) : []; + const metadata = { + license: { + edition, + features, + }, + }; + return metadata; + }); + // make this `/api`, for example, if your API is namespaced this.namespace = environmentConfig.api.namespace; // delay for each request, automatically set to 0 during testing diff --git a/addons/api/package.json b/addons/api/package.json index 12ebf1cc9..e558651e4 100644 --- a/addons/api/package.json +++ b/addons/api/package.json @@ -67,7 +67,7 @@ "prettier": "^2.6.2", "qunit": "^2.19.1", "qunit-dom": "^2.0.0", - "webpack": "^5.73.0" + "webpack": "^5.76.0" }, "engines": { "node": "12.* || 14.* || 16.*" diff --git a/addons/auth/package.json b/addons/auth/package.json index c229de74b..96c2d1e17 100644 --- a/addons/auth/package.json +++ b/addons/auth/package.json @@ -63,7 +63,7 @@ "prettier": "^2.6.2", "qunit": "^2.19.1", "qunit-dom": "^2.0.0", - "webpack": "^5.72.1" + "webpack": "^5.76.0" }, "engines": { "node": "12.* || 14.* || 16.*" diff --git a/addons/core/package.json b/addons/core/package.json index 0d1ee1cf4..ba8326be9 100644 --- a/addons/core/package.json +++ b/addons/core/package.json @@ -82,7 +82,7 @@ "qunit": "^2.19.1", "qunit-dom": "^2.0.0", "rose": "*", - "webpack": "^5.72.1" + "webpack": "^5.76.0" }, "engines": { "node": "12.* || 14.* || 16.*" diff --git a/addons/core/translations/actions/en-us.yaml b/addons/core/translations/actions/en-us.yaml index adf25337e..3198dc1bf 100644 --- a/addons/core/translations/actions/en-us.yaml +++ b/addons/core/translations/actions/en-us.yaml @@ -49,3 +49,4 @@ remove-resources: Remove resources and save do-this-later: Do this later toggle-color-theme: Toggle Color Theme toggle-feature-edition: Toggle Feature Edition +toggle-licensed-features: Toggle Licensed Features diff --git a/addons/core/translations/en-us.yaml b/addons/core/translations/en-us.yaml index 277e0dd3b..a482f52fc 100644 --- a/addons/core/translations/en-us.yaml +++ b/addons/core/translations/en-us.yaml @@ -38,11 +38,6 @@ titles: create-resources: Create Resources choose-an-option: Choose an option feature-edition: 'Edition: {edition}' -editions: - oss: OSS - ent: Enterprise - enterprise: Enterprise - hcp: HCP descriptions: empty-set: There are no items to display yet. You may be able to add items or try back later. cluster-url-initialization: To get started, please enter your cluster URL diff --git a/addons/rose/package.json b/addons/rose/package.json index fced03077..0b76441f3 100644 --- a/addons/rose/package.json +++ b/addons/rose/package.json @@ -109,7 +109,7 @@ "stylelint": "^14.14.0", "stylelint-config-prettier-scss": "^0.0.1", "stylelint-config-standard-scss": "^6.0.0", - "webpack": "^5.59.1" + "webpack": "^5.76.0" }, "engines": { "node": "12.* || 14.* || 16.*" diff --git a/ui/admin/app/instance-initializers/feature-edition.js b/ui/admin/app/instance-initializers/feature-edition.js index 54c11c9c3..957f7ceea 100644 --- a/ui/admin/app/instance-initializers/feature-edition.js +++ b/ui/admin/app/instance-initializers/feature-edition.js @@ -1,6 +1,39 @@ -export function initialize(owner) { +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import fetch from 'fetch'; + +async function autoInitializeFeatureEdition(owner) { const service = owner.lookup('service:feature-edition'); - service.initialize(); + const url = '/metadata.json'; + let edition; + let features; + + // Attempt to load edition for the metadata JSON + try { + const response = await fetch(url); + const json = await response.json(); + edition = json?.license?.edition; + features = json?.license?.features; + } catch (e) { + // if the request fails, the service will initialize the default edition + // as specified in the config + } + + // Initialize the feature edition and its associated features + service.initialize(edition, features); +} + +export async function initialize(owner) { + const config = owner.resolveRegistration('config:environment'); + const isTesting = config.environment === 'test'; + // Do not auto-init in a test environment. + // Tests should explicitly enable editions and features as needed. + if (!isTesting) { + await autoInitializeFeatureEdition(owner); + } } export default { diff --git a/ui/admin/app/routes/application.js b/ui/admin/app/routes/application.js index b5ca65df4..cbdbc109e 100644 --- a/ui/admin/app/routes/application.js +++ b/ui/admin/app/routes/application.js @@ -20,6 +20,7 @@ export default class ApplicationRoute extends Route { @service confirm; @service router; @service intl; + @service features; @service featureEdition; // =attributes @@ -132,4 +133,13 @@ export default class ApplicationRoute extends Route { toggleEdition(edition) { this.featureEdition.setEdition(edition); } + + @action + toggleFeature(feature) { + if (this.features.isEnabled(feature)) { + this.features.disable(feature); + } else { + this.features.enable(feature); + } + } } diff --git a/ui/admin/app/routes/scopes/scope/host-catalogs/host-catalog/host-sets/host-set/hosts/host.js b/ui/admin/app/routes/scopes/scope/host-catalogs/host-catalog/host-sets/host-set/hosts/host.js index a4c448d72..acfd23207 100644 --- a/ui/admin/app/routes/scopes/scope/host-catalogs/host-catalog/host-sets/host-set/hosts/host.js +++ b/ui/admin/app/routes/scopes/scope/host-catalogs/host-catalog/host-sets/host-set/hosts/host.js @@ -4,5 +4,22 @@ */ import Route from '@ember/routing/route'; +import { inject as service } from '@ember/service'; -export default class ScopesScopeHostCatalogsHostCatalogHostSetsHostSetHostsHostRoute extends Route {} +export default class ScopesScopeHostCatalogsHostCatalogHostSetsHostSetHostsHostRoute extends Route { + // =services + + @service store; + + // =methods + + /** + * Load a host in current scope. + * @param {object} params + * @param {string} params.host_id + * @return {HostModel} + */ + async model({ host_id }) { + return this.store.findRecord('host', host_id, { reload: true }); + } +} diff --git a/ui/admin/app/services/feature-edition.js b/ui/admin/app/services/feature-edition.js index 07112d25b..294bcc680 100644 --- a/ui/admin/app/services/feature-edition.js +++ b/ui/admin/app/services/feature-edition.js @@ -1,10 +1,13 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + import Service from '@ember/service'; import { inject as service } from '@ember/service'; import { tracked } from '@glimmer/tracking'; import config from 'admin/config/environment'; -const { selectedEdition, featureEditions } = config; - export default class FeatureEditionService extends Service { // =services @@ -12,24 +15,34 @@ export default class FeatureEditionService extends Service { // =attributes + licensedFeatures = Object.keys(config.features.licensedFeatures); + @tracked edition; // array of edition strings get editions() { - return Object.keys(featureEditions); + return Object.keys(config.features.featureEditions); } // =methods /** * Initializes the selected edition from the config. + * @param {string} edition + * @param {?string[]} enabledFeatures - list of extra features to enable */ - initialize() { - this.setEdition(selectedEdition); + initialize(edition, enabledFeatures) { + this.setEdition(edition || config.features.defaultEdition, enabledFeatures); } - setEdition(edition) { - const editionFlags = featureEditions[edition]; + /** + * Enables the specified edition. + * @param {string} edition + * @param {?string[]} enabledFeatures - list of extra features to enable + */ + setEdition(edition, enabledFeatures) { + this.edition = edition; + const editionFlags = config.features.featureEditions[edition]; Object.keys(editionFlags).forEach((flag) => { if (editionFlags[flag]) { this.features.enable(flag); @@ -37,6 +50,8 @@ export default class FeatureEditionService extends Service { this.features.disable(flag); } }); - this.edition = edition; + if (enabledFeatures) { + enabledFeatures.forEach((flag) => this.features.enable(flag)); + } } } diff --git a/ui/admin/app/templates/application.hbs b/ui/admin/app/templates/application.hbs index 4c4b34805..8bd7a7574 100644 --- a/ui/admin/app/templates/application.hbs +++ b/ui/admin/app/templates/application.hbs @@ -73,7 +73,7 @@ data-test-dev-edition-toggle @text={{t 'titles.feature-edition' - edition=(t (concat 'editions.' this.featureEdition.edition)) + edition=this.featureEdition.edition }} @icon='flight-icons/svg/layers-16' as |dropdown| @@ -89,7 +89,7 @@ {{#each this.featureEdition.editions as |edition|}} @@ -97,6 +97,20 @@ + + + + {{#each this.featureEdition.licensedFeatures as |feature|}} + + + + {{/each}} + + {{/if}} diff --git a/ui/admin/app/templates/scopes/scope/host-catalogs/host-catalog/hosts/host/index.hbs b/ui/admin/app/templates/scopes/scope/host-catalogs/host-catalog/hosts/host/index.hbs index deca7e140..7ab0010c7 100644 --- a/ui/admin/app/templates/scopes/scope/host-catalogs/host-catalog/hosts/host/index.hbs +++ b/ui/admin/app/templates/scopes/scope/host-catalogs/host-catalog/hosts/host/index.hbs @@ -17,7 +17,7 @@ - + diff --git a/ui/admin/config/environment.js b/ui/admin/config/environment.js index a6fb109fb..17df14226 100644 --- a/ui/admin/config/environment.js +++ b/ui/admin/config/environment.js @@ -5,12 +5,27 @@ 'use strict'; -const features = require('./features'); +const v8 = require('v8'); +const { + defaultEdition, + featureEditions, + licensedFeatures, +} = require('./features'); const APP_NAME = process.env.APP_NAME || 'Boundary'; const API_HOST = process.env.API_HOST || ''; +const clone = (obj) => v8.deserialize(v8.serialize(obj)); + module.exports = function (environment) { + // Start with a fresh copy of the features config every run, since it + // could be modified by an environment. + const features = { + defaultEdition, + featureEditions: clone(featureEditions), + licensedFeatures: clone(licensedFeatures), + }; + let ENV = { modulePrefix: 'admin', environment, @@ -100,8 +115,7 @@ module.exports = function (environment) { timeout: 4000, }, - selectedEdition: features.selectedEdition, - featureEditions: features.featureEditions, + features: features, featureFlags: {}, }; @@ -127,14 +141,16 @@ module.exports = function (environment) { }; // Default edition in development - ENV.selectedEdition = 'enterprise'; - features.enableFeaturesInAllEditions( - { - // Show edition toggle in UI in development - 'dev-edition-toggle': true, - }, - ENV - ); + ENV.features.defaultEdition = 'enterprise'; + // Enable development-only features + ENV.features.featureEditions.oss['dev-edition-toggle'] = true; + ENV.features.featureEditions.enterprise['dev-edition-toggle'] = true; + ENV.features.featureEditions.hcp['dev-edition-toggle'] = true; + // Enable licensed features by default in enterprise and hcp + Object.keys(ENV.features.licensedFeatures).forEach((feature) => { + ENV.features.featureEditions.enterprise[feature] = true; + ENV.features.featureEditions.hcp[feature] = true; + }); } if (environment === 'test') { @@ -152,16 +168,6 @@ module.exports = function (environment) { ENV.flashMessageDefaults.timeout = 0; ENV.enableConfirmService = false; - - /** - * Enable additional features for testing purposes. - * [TODO] Tests should be refactored such that each test case - * explicitly enables the features and/or edition that it needs. - * By default, tests should have no features enabled. This explicit - * approach ensures that test cases are easy to read and understand, - * since their feature requirements are embedded. - */ - ENV.selectedEdition = 'enterprise'; } if (environment === 'production') { diff --git a/ui/admin/config/features.js b/ui/admin/config/features.js index 5af97dfff..55bc8abbb 100644 --- a/ui/admin/config/features.js +++ b/ui/admin/config/features.js @@ -1,13 +1,26 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + const EDITION = process.env.EDITION || 'oss'; // Default edition is OSS -const selectedEdition = EDITION; +const defaultEdition = EDITION; +const devFeatures = { + 'dev-edition-toggle': false, +}; +const licensedFeatures = { + 'multi-hop-sessions': false, + 'ssh-target': false, +}; // Base edition declares available features, disabled by default. const baseEdition = { + ...devFeatures, + ...licensedFeatures, byow: false, 'byow-pki-hcp-cluster-id': false, 'json-credentials': false, - 'ssh-target': false, 'static-credentials': false, 'target-worker-filters-v2': false, 'target-worker-filters-v2-ingress': false, @@ -28,7 +41,6 @@ featureEditions.oss = { }; featureEditions.enterprise = { ...featureEditions.oss, - 'ssh-target': true, 'target-worker-filters-v2-ingress': true, 'vault-worker-filter': true, 'session-recording': true, @@ -39,18 +51,8 @@ featureEditions.hcp = { 'target-worker-filters-v2-hcp': true, }; -/** - * Takes a set of features and enables them in all editions. - * For use in development and testing only. - */ -const enableFeaturesInAllEditions = (features = {}, ENV) => { - Object.entries(featureEditions).forEach( - ([key, edition]) => (ENV.featureEditions[key] = { ...features, ...edition }) - ); -}; - module.exports = { featureEditions, - selectedEdition, - enableFeaturesInAllEditions, + defaultEdition, + licensedFeatures, }; diff --git a/ui/admin/package.json b/ui/admin/package.json index 4f0273108..3701d3c36 100644 --- a/ui/admin/package.json +++ b/ui/admin/package.json @@ -101,7 +101,7 @@ "stylelint": "^14.14.0", "stylelint-config-prettier-scss": "^0.0.1", "stylelint-config-standard-scss": "^6.0.0", - "webpack": "^5.72.1" + "webpack": "^5.76.0" }, "engines": { "node": "12.* || 14.* || 16.*" diff --git a/ui/admin/tests/acceptance/credential-library/create-test.js b/ui/admin/tests/acceptance/credential-library/create-test.js index 7f0343574..dc9cfe2d1 100644 --- a/ui/admin/tests/acceptance/credential-library/create-test.js +++ b/ui/admin/tests/acceptance/credential-library/create-test.js @@ -23,6 +23,7 @@ module('Acceptance | credential-libraries | create', function (hooks) { setupApplicationTest(hooks); setupMirage(hooks); + let featuresService; let getCredentialLibraryCount; const instances = { @@ -76,6 +77,7 @@ module('Acceptance | credential-libraries | create', function (hooks) { getCredentialLibraryCount = () => this.server.schema.credentialLibraries.all().models.length; authenticateSession({}); + featuresService = this.owner.lookup('service:features'); }); test('visiting credential libraries', async function (assert) { assert.expect(2); @@ -98,6 +100,7 @@ module('Acceptance | credential-libraries | create', function (hooks) { test('can create a new credential library of type vault ssh cert', async function (assert) { assert.expect(12); + featuresService.enable('ssh-target'); const count = getCredentialLibraryCount(); await visit(urls.newCredentialLibrary); await click('[value="vault-ssh-certificate"]'); @@ -156,6 +159,7 @@ module('Acceptance | credential-libraries | create', function (hooks) { test('ecdsa and rsa key types bring up a key bits field', async function (assert) { assert.expect(3); + featuresService.enable('ssh-target'); await visit(urls.newCredentialLibrary); await click('[value="vault-ssh-certificate"]'); await select('[name="key_type"]', 'ed25519'); @@ -224,11 +228,9 @@ module('Acceptance | credential-libraries | create', function (hooks) { }); test('cannot select vault ssh cert when feature is disabled', async function (assert) { - const featuresService = this.owner.lookup('service:features'); - featuresService.disable('ssh-target'); - assert.expect(1); + assert.expect(2); await visit(urls.newCredentialLibrary); - + assert.false(featuresService.isEnabled('ssh-target')); assert.dom('[value="vault-ssh-certificate"]').doesNotExist(); }); }); diff --git a/ui/admin/tests/acceptance/credential-library/read-test.js b/ui/admin/tests/acceptance/credential-library/read-test.js index 38cf3f406..3194db43a 100644 --- a/ui/admin/tests/acceptance/credential-library/read-test.js +++ b/ui/admin/tests/acceptance/credential-library/read-test.js @@ -85,7 +85,7 @@ module('Acceptance | credential-libraries | read', function (hooks) { }); test('cannot navigate to vault ssh cert form when feature is not enabled', async function (assert) { - assert.expect(1); + assert.expect(2); instances.credentialLibrary = this.server.create('credential-library', { scope: instances.scopes.project, credentialStore: instances.credentialStore, @@ -94,10 +94,9 @@ module('Acceptance | credential-libraries | read', function (hooks) { await visit( `${urls.credentialLibraries}/${instances.credentialLibrary.id}` ); - const featuresService = this.owner.lookup('service:features'); - featuresService.disable('ssh-target'); await visit(urls.credentialLibraries); - + const featuresService = this.owner.lookup('service:features'); + assert.false(featuresService.isEnabled('ssh-target')); assert.dom('.rose-table-body tr:nth-of-type(2) a').doesNotExist(); }); diff --git a/ui/admin/tests/acceptance/credential-store/create-test.js b/ui/admin/tests/acceptance/credential-store/create-test.js index 780023fdd..6fc90f3f9 100644 --- a/ui/admin/tests/acceptance/credential-store/create-test.js +++ b/ui/admin/tests/acceptance/credential-store/create-test.js @@ -14,6 +14,7 @@ module('Acceptance | credential-stores | create', function (hooks) { setupApplicationTest(hooks); setupMirage(hooks); + let featuresService; let getCredentialStoresCount; let getStaticCredentialStoresCount; let getVaultCredentialStoresCount; @@ -62,10 +63,12 @@ module('Acceptance | credential-stores | create', function (hooks) { .length; }; authenticateSession({}); + featuresService = this.owner.lookup('service:features'); }); test('Users can create a new credential store of default type static', async function (assert) { assert.expect(1); + featuresService.enable('static-credentials'); const count = getStaticCredentialStoresCount(); await visit(urls.newCredentialStore); await fillIn('[name="name"]', 'random string'); @@ -75,6 +78,7 @@ module('Acceptance | credential-stores | create', function (hooks) { test('Users can create a new credential store of type vault', async function (assert) { assert.expect(1); + featuresService.enable('static-credentials'); const count = getVaultCredentialStoresCount(); await visit(urls.newCredentialStore); await fillIn('[name="name"]', 'random string'); diff --git a/ui/admin/tests/acceptance/credential-store/credentials/create-test.js b/ui/admin/tests/acceptance/credential-store/credentials/create-test.js index 1276bf965..67133fb92 100644 --- a/ui/admin/tests/acceptance/credential-store/credentials/create-test.js +++ b/ui/admin/tests/acceptance/credential-store/credentials/create-test.js @@ -117,6 +117,7 @@ module( test('users can create a new json credential', async function (assert) { assert.expect(2); + featuresService.enable('json-credentials'); const credentialsCount = getCredentialsCount(); const jsonCredentialCount = getJsonCredentialCount(); await visit(urls.credentials); @@ -159,6 +160,7 @@ module( test('users can cancel create new json credential', async function (assert) { assert.expect(2); + featuresService.enable('json-credentials'); const credentialsCount = getCredentialsCount(); await visit(urls.credentials); @@ -173,6 +175,7 @@ module( test('users can switch away from JSON type credentials and the json_object value will be cleared', async function (assert) { assert.expect(2); + featuresService.enable('json-credentials'); const editorSelector = '[data-test-code-editor-field-editor]'; const newSecret = '{"test": "value"}'; @@ -191,6 +194,7 @@ module( test('users cannot navigate to new credential route without proper authorization', async function (assert) { assert.expect(2); + featuresService.enable('static-credentials'); instances.staticCredentialStore.authorized_collection_actions.credentials = instances.staticCredentialStore.authorized_collection_actions.credentials.filter( (item) => { @@ -282,6 +286,7 @@ module( test('saving a new json credential with invalid fields displays error messages', async function (assert) { assert.expect(1); + featuresService.enable('json-credentials'); await visit(urls.credentials); this.server.post('/credentials', () => { return new Response( @@ -313,12 +318,11 @@ module( }); test('cannot navigate to json credential when feature is disabled', async function (assert) { - featuresService.disable('json-credentials'); - assert.expect(4); + assert.expect(5); await visit(urls.credentials); await click(`[href="${urls.newCredential}"]`); - + assert.false(featuresService.isEnabled('json-credentials')); assert.true( instances.staticCredentialStore.authorized_collection_actions.credentials.includes( 'create' diff --git a/ui/admin/tests/acceptance/credential-store/credentials/read-test.js b/ui/admin/tests/acceptance/credential-store/credentials/read-test.js index 6739b54ea..09ccfb301 100644 --- a/ui/admin/tests/acceptance/credential-store/credentials/read-test.js +++ b/ui/admin/tests/acceptance/credential-store/credentials/read-test.js @@ -14,6 +14,8 @@ module('Acceptance | credential-stores | credentials | read', function (hooks) { setupApplicationTest(hooks); setupMirage(hooks); + let featuresService; + const instances = { scopes: { org: null, @@ -75,6 +77,7 @@ module('Acceptance | credential-stores | credentials | read', function (hooks) { urls.jsonCredential = `${urls.credentials}/${instances.jsonCredential.id}`; urls.unknownCredential = `${urls.credentials}/foo`; authenticateSession({}); + featuresService = this.owner.lookup('service:features'); }); test('visiting username & password credential', async function (assert) { @@ -101,6 +104,7 @@ module('Acceptance | credential-stores | credentials | read', function (hooks) { test('visiting JSON credential', async function (assert) { assert.expect(2); + featuresService.enable('json-credentials'); await visit(urls.staticCredentialStore); await click(`[href="${urls.credentials}"]`); await a11yAudit(); @@ -141,10 +145,9 @@ module('Acceptance | credential-stores | credentials | read', function (hooks) { }); test('cannot navigate to a JSON credential form when feature not enabled', async function (assert) { - assert.expect(1); - const featuresService = this.owner.lookup('service:features'); - featuresService.disable('json-credentials'); + assert.expect(2); await visit(urls.credentials); + assert.false(featuresService.isEnabled('json-credentials')); assert.dom('.rose-table-body tr:nth-child(3) a').doesNotExist(); }); diff --git a/ui/admin/tests/acceptance/credential-store/read-test.js b/ui/admin/tests/acceptance/credential-store/read-test.js index b7661aef7..f8d7bc38f 100644 --- a/ui/admin/tests/acceptance/credential-store/read-test.js +++ b/ui/admin/tests/acceptance/credential-store/read-test.js @@ -14,6 +14,8 @@ module('Acceptance | credential-stores | read', function (hooks) { setupApplicationTest(hooks); setupMirage(hooks); + let featuresService; + const instances = { scopes: { global: null, @@ -63,10 +65,12 @@ module('Acceptance | credential-stores | read', function (hooks) { urls.unknownCredentialStore = `${urls.credentialStores}/foo`; authenticateSession({}); + featuresService = this.owner.lookup('service:features'); }); test('visiting static credential store', async function (assert) { assert.expect(2); + featuresService.enable('static-credentials'); await visit(urls.credentialStores); await a11yAudit(); assert.strictEqual(currentURL(), urls.credentialStores); @@ -104,6 +108,7 @@ module('Acceptance | credential-stores | read', function (hooks) { test('cannot navigate to a vault credential store form without proper authorization', async function (assert) { assert.expect(2); + featuresService.enable('static-credentials'); await visit(urls.projectScope); instances.vaultCredentialStore.authorized_actions = instances.vaultCredentialStore.authorized_actions.filter( diff --git a/ui/admin/tests/acceptance/develop-test.js b/ui/admin/tests/acceptance/develop-test.js index 9f6e8ae4a..f70fc1992 100644 --- a/ui/admin/tests/acceptance/develop-test.js +++ b/ui/admin/tests/acceptance/develop-test.js @@ -1,3 +1,8 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + import { module, test } from 'qunit'; import { visit, getContext } from '@ember/test-helpers'; import { setupApplicationTest } from 'admin/tests/helpers'; @@ -15,12 +20,14 @@ module('Acceptance | develop', function (hooks) { }); test('edition toggle is hidden when `dev-edition-toggle` is false', async function (assert) { + assert.expect(2); await visit('/'); assert.false(featuresService.isEnabled('dev-edition-toggle')); assert.dom('data-dev-edition-toggle').doesNotExist(); }); test('edition toggle is visible when `dev-edition-toggle` is true', async function (assert) { + assert.expect(2); assert.false(featuresService.isEnabled('dev-edition-toggle')); featuresService.enable('dev-edition-toggle'); await visit('/'); diff --git a/ui/admin/tests/acceptance/session-recordings/read-test.js b/ui/admin/tests/acceptance/session-recordings/read-test.js index 8d5c60a9e..3c169c929 100644 --- a/ui/admin/tests/acceptance/session-recordings/read-test.js +++ b/ui/admin/tests/acceptance/session-recordings/read-test.js @@ -9,6 +9,8 @@ module('Acceptance | session recordings | read', function (hooks) { setupApplicationTest(hooks); setupMirage(hooks); + let featuresService; + // Selectors const LIST_SESSION_RECORDING_BUTTON = 'table > tbody > tr > td:last-child > a'; @@ -51,26 +53,26 @@ module('Acceptance | session recordings | read', function (hooks) { urls.sessionRecording = `${urls.sessionRecordings}/${instances.sessionRecording.id}`; urls.channelRecording = `${urls.sessionRecording}/channels-by-connection/${instances.channelRecording.id}`; authenticateSession({}); + featuresService = this.owner.lookup('service:features'); }); test('visiting a session recording', async function (assert) { assert.expect(1); + featuresService.enable('session-recording'); // Visit session recordings await visit(urls.sessionRecordings); await a11yAudit(); - // Click a session recording and check it navigates properly await click(LIST_SESSION_RECORDING_BUTTON); await a11yAudit(); - assert.strictEqual(currentURL(), urls.sessionRecording); }); test('user can navigate to a session recording with proper authorization', async function (assert) { assert.expect(3); + featuresService.enable('session-recording'); // Visit session recordings await visit(urls.sessionRecordings); - assert.true(instances.sessionRecording.authorized_actions.includes('read')); assert.dom(`[href="${urls.sessionRecording}"]`).exists(); // Click a session recording and check it navigates properly @@ -80,11 +82,11 @@ module('Acceptance | session recordings | read', function (hooks) { test('user cannot navigate to a session recording without the read action', async function (assert) { assert.expect(1); + featuresService.enable('session-recording'); instances.sessionRecording.authorized_actions = instances.sessionRecording.authorized_actions.filter( (item) => item !== 'read' ); - // Visit session recordings await visit(urls.sessionRecordings); assert.dom(LIST_SESSION_RECORDING_BUTTON).doesNotExist(); @@ -92,7 +94,7 @@ module('Acceptance | session recordings | read', function (hooks) { test('user can navigate to a channel recording', async function (assert) { assert.expect(2); - + featuresService.enable('session-recording'); // Visit session recording await visit(urls.sessionRecording); assert.dom('table').hasClass('hds-table'); diff --git a/ui/admin/tests/acceptance/storage-buckets/list-test.js b/ui/admin/tests/acceptance/storage-buckets/list-test.js index c81abb0b2..9a810afa8 100644 --- a/ui/admin/tests/acceptance/storage-buckets/list-test.js +++ b/ui/admin/tests/acceptance/storage-buckets/list-test.js @@ -13,7 +13,7 @@ module('Acceptance | storage-buckets | list', function (hooks) { setupApplicationTest(hooks); setupMirage(hooks); - let features; + let featuresService; let intl; const STORAGE_BUCKET_TITLE = 'Storage Buckets'; @@ -46,14 +46,14 @@ module('Acceptance | storage-buckets | list', function (hooks) { urls.storageBuckets = `${urls.globalScope}/storage-buckets`; intl = this.owner.lookup('service:intl'); - features = this.owner.lookup('service:features'); - features.enable('session-recording'); + authenticateSession({}); + featuresService = this.owner.lookup('service:features'); }); test('users can navigate to storage-buckets with proper authorization', async function (assert) { assert.expect(5); - + featuresService.enable('session-recording'); await visit(urls.globalScope); assert.true( @@ -79,6 +79,9 @@ module('Acceptance | storage-buckets | list', function (hooks) { test('user cannot navigate to index without either list or create actions', async function (assert) { assert.expect(5); + featuresService.enable('byow'); + featuresService.enable('session-recording'); + instances.scopes.global.authorized_collection_actions['storage-buckets'] = []; @@ -111,6 +114,8 @@ module('Acceptance | storage-buckets | list', function (hooks) { test('user can navigate to index with only create action', async function (assert) { assert.expect(5); + featuresService.enable('session-recording'); + instances.scopes.global.authorized_collection_actions['storage-buckets'] = instances.scopes.global.authorized_collection_actions[ 'storage-buckets' @@ -143,6 +148,8 @@ module('Acceptance | storage-buckets | list', function (hooks) { test('user can navigate to index with only list action', async function (assert) { assert.expect(5); + featuresService.enable('session-recording'); + instances.scopes.global.authorized_collection_actions['storage-buckets'] = instances.scopes.global.authorized_collection_actions[ 'storage-buckets' @@ -172,11 +179,10 @@ module('Acceptance | storage-buckets | list', function (hooks) { }); test('user cannot navigate to index when feature is disabled', async function (assert) { - assert.expect(1); - features.disable('session-recording'); - + assert.expect(2); + featuresService.enable('byow'); await visit(urls.globalScope); - + assert.false(featuresService.isEnabled('session-recording')); assert .dom('[title="General"] a:nth-of-type(2)') .doesNotIncludeText(STORAGE_BUCKET_TITLE); @@ -184,6 +190,7 @@ module('Acceptance | storage-buckets | list', function (hooks) { test('edit action in table directs user to appropriate page', async function (assert) { assert.expect(3); + featuresService.enable('session-recording'); await visit(urls.globalScope); instances.storageBucket = this.server.create('storage-bucket', { scope: instances.scopes.global, diff --git a/ui/admin/tests/acceptance/targets/brokered-credential-sources-test.js b/ui/admin/tests/acceptance/targets/brokered-credential-sources-test.js index 5f556fd6f..eb6e47021 100644 --- a/ui/admin/tests/acceptance/targets/brokered-credential-sources-test.js +++ b/ui/admin/tests/acceptance/targets/brokered-credential-sources-test.js @@ -148,14 +148,13 @@ module('Acceptance | targets | brokered credential sources', function (hooks) { }); test('cannot navigate to a json type credential when feature is disabled', async function (assert) { - featuresService.disable('json-credentials'); - assert.expect(2); + assert.expect(3); const jsonCredential = instances.credentials[2]; instances.target.update({ brokeredCredentialSourceIds: [...randomlySelectedCredentials], }); await visit(urls.brokeredCredentialSources); - + assert.false(featuresService.isEnabled('json-credentials')); assert .dom('.rose-table-row:nth-child(3)') .includesText(jsonCredential.name); diff --git a/ui/admin/tests/acceptance/targets/create-test.js b/ui/admin/tests/acceptance/targets/create-test.js index d5ff06eab..86f3ced0d 100644 --- a/ui/admin/tests/acceptance/targets/create-test.js +++ b/ui/admin/tests/acceptance/targets/create-test.js @@ -85,13 +85,17 @@ module('Acceptance | targets | create', function (hooks) { test('defaults to type `ssh` when no query param provided', async function (assert) { assert.expect(1); + featuresService.enable('ssh-target'); await visit(urls.newTarget); assert.strictEqual(find('[name="type"]:checked').value, TYPE_TARGET_SSH); }); test('can create type `ssh` when `target-worker-filters-v2` is disabled', async function (assert) { - featuresService.disable('target-worker-filters-v2'); - assert.expect(4); + assert.expect(5); + featuresService.enable('ssh-target'); + + assert.false(featuresService.isEnabled('target-worker-filters-v2')); + const targetCount = getTargetCount(); const sshTargetCount = getSSHTargetCount(); await visit(urls.targets); @@ -116,8 +120,10 @@ module('Acceptance | targets | create', function (hooks) { }); test('can create type `ssh` when `target-worker-filters-v2` is enabled', async function (assert) { - featuresService.enable('target-worker-filters-v2'); assert.expect(4); + featuresService.enable('ssh-target'); + featuresService.enable('target-worker-filters-v2'); + const targetCount = getTargetCount(); const sshTargetCount = getSSHTargetCount(); await visit(urls.targets); @@ -146,8 +152,11 @@ module('Acceptance | targets | create', function (hooks) { }); test('can create type `tcp` when `target-worker-filters-v2` is disabled', async function (assert) { - featuresService.disable('target-worker-filters-v2'); - assert.expect(4); + assert.expect(5); + featuresService.enable('ssh-target'); + + assert.false(featuresService.isEnabled('target-worker-filters-v2')); + const targetCount = getTargetCount(); const tcpTargetCount = getTCPTargetCount(); await visit(urls.targets); @@ -172,8 +181,10 @@ module('Acceptance | targets | create', function (hooks) { }); test('can create type `tcp` when `target-worker-filters-v2` is enabled', async function (assert) { - featuresService.enable('target-worker-filters-v2'); assert.expect(4); + featuresService.enable('ssh-target'); + featuresService.enable('target-worker-filters-v2'); + const targetCount = getTargetCount(); const tcpTargetCount = getTCPTargetCount(); await visit(urls.targets); @@ -203,9 +214,11 @@ module('Acceptance | targets | create', function (hooks) { }); test('can create type `tcp` when `target-worker-filters-v2` and `target-worker-filters-v2-ingress` is enabled', async function (assert) { + assert.expect(4); + featuresService.enable('ssh-target'); featuresService.enable('target-worker-filters-v2'); featuresService.enable('target-worker-filters-v2-ingress'); - assert.expect(4); + const targetCount = getTargetCount(); const tcpTargetCount = getTCPTargetCount(); await visit(urls.targets); @@ -239,15 +252,16 @@ module('Acceptance | targets | create', function (hooks) { test('default port is not marked required for SSH targets', async function (assert) { assert.expect(1); + featuresService.enable('ssh-target'); await visit(urls.newTarget); assert.dom('[data-test-default-port-label]').includesText('Optional'); }); test('default port is marked required for TCP targets', async function (assert) { assert.expect(1); + featuresService.enable('ssh-target'); await visit(urls.newTarget); await click('[value="tcp"]'); - assert.dom('[data-test-default-port-label]').includesText('Required'); }); @@ -284,12 +298,11 @@ module('Acceptance | targets | create', function (hooks) { }); test('cannot navigate to new SSH targets route when ssh feature is disabled', async function (assert) { - assert.expect(3); - featuresService.disable('ssh-target'); + assert.expect(4); await visit(urls.targets); await click(`[href="${urls.newTarget}"]`); - + assert.false(featuresService.isEnabled('ssh-target')); assert.true( instances.scopes.project.authorized_collection_actions.targets.includes( 'create' @@ -301,6 +314,9 @@ module('Acceptance | targets | create', function (hooks) { test('can cancel create new TCP target', async function (assert) { assert.expect(3); + featuresService.enable('target-worker-filters-v2'); + featuresService.enable('target-worker-filters-v2-ingress'); + const targetCount = getTargetCount(); const tcpTargetCount = getTCPTargetCount(); await visit(urls.targets); @@ -321,6 +337,10 @@ module('Acceptance | targets | create', function (hooks) { test('can cancel create new SSH target', async function (assert) { assert.expect(3); + featuresService.enable('ssh-target'); + featuresService.enable('target-worker-filters-v2'); + featuresService.enable('target-worker-filters-v2-ingress'); + const targetCount = getTargetCount(); const sshTargetCount = getSSHTargetCount(); await visit(urls.targets); @@ -398,10 +418,13 @@ module('Acceptance | targets | create', function (hooks) { test('can save address', async function (assert) { assert.expect(2); + featuresService.enable('target-network-address'); + const targetCount = getTargetCount(); await visit(urls.targets); await click(`[href="${urls.newTarget}"]`); + await fillIn('[name="name"]', 'random string'); await fillIn('[name="address"]', '0.0.0.0'); await click('[type="submit"]'); @@ -414,12 +437,10 @@ module('Acceptance | targets | create', function (hooks) { }); test('address field does not exist when target network address feature is disabled', async function (assert) { - assert.expect(1); - featuresService.disable('target-network-address'); + assert.expect(2); await visit(urls.targets); - await click(`[href="${urls.newTarget}"]`); - + assert.false(featuresService.isEnabled('target-network-address')); assert.dom('[name="address"]').doesNotExist(); }); }); diff --git a/ui/admin/tests/acceptance/targets/read-test.js b/ui/admin/tests/acceptance/targets/read-test.js index 76c054a0d..7a9fdf1e4 100644 --- a/ui/admin/tests/acceptance/targets/read-test.js +++ b/ui/admin/tests/acceptance/targets/read-test.js @@ -76,6 +76,8 @@ module('Acceptance | targets | read', function (hooks) { test('visiting ssh target', async function (assert) { assert.expect(2); + featuresService.enable('ssh-target'); + await visit(urls.targets); await a11yAudit(); assert.strictEqual(currentURL(), urls.targets); @@ -134,23 +136,22 @@ module('Acceptance | targets | read', function (hooks) { }); test('visiting an ssh target does not show the worker_filter deprecation message when "target-worker-filters-v2" is disabled', async function (assert) { - featuresService.disable('target-worker-filters-v2'); - assert.expect(1); + assert.expect(2); await visit(urls.sshTarget); - + assert.false(featuresService.isEnabled('target-worker-filters-v2')); assert.dom('.hds-alert').doesNotExist(); }); test('visiting a tcp target does not show the worker_filter deprecation message when "target-worker-filters-v2" is disabled', async function (assert) { - featuresService.disable('target-worker-filters-v2'); - assert.expect(1); + assert.expect(2); await visit(urls.tcpTarget); - + assert.false(featuresService.isEnabled('target-worker-filters-v2')); assert.dom('.hds-alert').doesNotExist(); }); - test('cannot navigate to a ssh target form without proper authorization', async function (assert) { + test('cannot navigate to an ssh target form without proper authorization', async function (assert) { assert.expect(2); + featuresService.enable('ssh-target'); await visit(urls.projectScope); instances.sshTarget.authorized_actions = instances.sshTarget.authorized_actions.filter((item) => item !== 'read'); @@ -163,6 +164,7 @@ module('Acceptance | targets | read', function (hooks) { test('cannot navigate to a tcp target form without proper authorization', async function (assert) { assert.expect(2); + featuresService.enable('ssh-target'); await visit(urls.projectScope); instances.tcpTarget.authorized_actions = instances.tcpTarget.authorized_actions.filter((item) => item !== 'read'); diff --git a/ui/admin/tests/acceptance/targets/update-test.js b/ui/admin/tests/acceptance/targets/update-test.js index ac7455b66..02f0b597e 100644 --- a/ui/admin/tests/acceptance/targets/update-test.js +++ b/ui/admin/tests/acceptance/targets/update-test.js @@ -39,7 +39,6 @@ module('Acceptance | targets | update', function (hooks) { hooks.beforeEach(function () { featuresService = this.owner.lookup('service:features'); - featuresService.disable('target-worker-filters-v2'); // Generate resources instances.scopes.global = this.server.create('scope', { id: 'global' }); instances.scopes.org = this.server.create('scope', { @@ -96,10 +95,9 @@ module('Acceptance | targets | update', function (hooks) { }); test('updating a target does not show the worker_filter deprecation message when "target-worker-filters-v2" is disabled', async function (assert) { - featuresService.disable('target-worker-filters-v2'); - assert.expect(1); + assert.expect(2); await visit(urls.target); - + assert.false(featuresService.isEnabled('target-worker-filters-v2')); assert.dom('.hds-alert').doesNotExist(); }); @@ -366,6 +364,8 @@ module('Acceptance | targets | update', function (hooks) { test('saving address with existing host sources brings up confirmation modal and removes host sources', async function (assert) { assert.expect(4); + featuresService.enable('ssh-target'); + featuresService.enable('target-network-address'); const confirmService = this.owner.lookup('service:confirm'); confirmService.enabled = true; this.server.createList( @@ -410,6 +410,8 @@ module('Acceptance | targets | update', function (hooks) { test('saving address with existing host sources brings up confirmation modal and can cancel', async function (assert) { assert.expect(4); + featuresService.enable('ssh-target'); + featuresService.enable('target-network-address'); const confirmService = this.owner.lookup('service:confirm'); confirmService.enabled = true; this.server.createList( diff --git a/ui/admin/tests/acceptance/workers/create-test.js b/ui/admin/tests/acceptance/workers/create-test.js index 7d98fe115..fefe6584c 100644 --- a/ui/admin/tests/acceptance/workers/create-test.js +++ b/ui/admin/tests/acceptance/workers/create-test.js @@ -54,21 +54,21 @@ module('Acceptance | workers | create', function (hooks) { }); test('initial upstreams input field is visible for `oss` binary', async function (assert) { - assert.expect(2); + assert.expect(3); const featuresService = this.owner.lookup('service:features'); - featuresService.disable('byow-pki-hcp-cluster-id'); await visit(newWorkerURL); const labels = findAll('label.rose-form-label'); + assert.false(featuresService.isEnabled('byow-pki-hcp-cluster-id')); assert.dom(labels[0]).doesNotIncludeText('Boundary Cluster ID'); assert.dom(labels[2]).hasText('Initial Upstreams'); }); test('download and install step shows correct oss instructions', async function (assert) { - assert.expect(2); + assert.expect(3); const featuresService = this.owner.lookup('service:features'); - featuresService.disable('byow-pki-hcp-cluster-id'); await visit(newWorkerURL); const createSection = findAll('.worker-create-section'); + assert.false(featuresService.isEnabled('byow-pki-hcp-cluster-id')); assert.dom(createSection[1]).includesText('curl -fsSL'); assert.dom(createSection[1]).doesNotIncludeText('wget -q'); }); diff --git a/ui/admin/tests/acceptance/workers/list-test.js b/ui/admin/tests/acceptance/workers/list-test.js index 404741a53..2899b01d3 100644 --- a/ui/admin/tests/acceptance/workers/list-test.js +++ b/ui/admin/tests/acceptance/workers/list-test.js @@ -18,6 +18,8 @@ module('Acceptance | workers | list', function (hooks) { setupApplicationTest(hooks); setupMirage(hooks); + let featuresService; + const instances = { scopes: { global: null, @@ -31,14 +33,15 @@ module('Acceptance | workers | list', function (hooks) { hooks.beforeEach(function () { instances.scopes.global = this.server.create('scope', { id: 'global' }); - urls.globalScope = `/scopes/global/scopes`; urls.workers = `/scopes/global/workers`; authenticateSession({}); + featuresService = this.owner.lookup('service:features'); }); test('Users can navigate to workers with proper authorization', async function (assert) { assert.expect(2); + featuresService.enable('byow'); await visit(urls.globalScope); assert.ok( instances.scopes.global.authorized_collection_actions.workers.includes( @@ -50,6 +53,7 @@ module('Acceptance | workers | list', function (hooks) { test('Users cannot navigate to workers without list or create permissions', async function (assert) { assert.expect(1); + featuresService.enable('byow'); instances.scopes.global.authorized_collection_actions.workers = []; await visit(urls.globalScope); @@ -58,6 +62,7 @@ module('Acceptance | workers | list', function (hooks) { test('Users can navigate to workers with only create permission', async function (assert) { assert.expect(1); + featuresService.enable('byow'); instances.scopes.global.authorized_collection_actions.workers = [ 'create:worker-led', ]; @@ -68,6 +73,7 @@ module('Acceptance | workers | list', function (hooks) { test('Users can navigate to workers with only list permission', async function (assert) { assert.expect(1); + featuresService.enable('byow'); instances.scopes.global.authorized_collection_actions.workers = ['list']; await visit(urls.globalScope); diff --git a/ui/admin/tests/integration/components/worker-diagram/dual-filter/hcp/index-test.js b/ui/admin/tests/integration/components/worker-diagram/dual-filter/hcp/index-test.js index fa56d0aa1..3b7b20625 100644 --- a/ui/admin/tests/integration/components/worker-diagram/dual-filter/hcp/index-test.js +++ b/ui/admin/tests/integration/components/worker-diagram/dual-filter/hcp/index-test.js @@ -16,13 +16,11 @@ module( setupIntl(hooks); let featuresService; - const targetWorkerFilterIngress = 'target-worker-filters-v2-ingress'; const targetWorkerFilterHCP = 'target-worker-filters-v2-hcp'; hooks.beforeEach(function () { featuresService = this.owner.lookup('service:features'); featuresService.enable(targetWorkerFilterHCP); - featuresService.disable(targetWorkerFilterIngress); }); test('it renders the correct diagram when egress and ingress filter is false', async function (assert) { diff --git a/ui/admin/tests/integration/components/worker-diagram/dual-filter/index-test.js b/ui/admin/tests/integration/components/worker-diagram/dual-filter/index-test.js index 0312201ee..fa620972f 100644 --- a/ui/admin/tests/integration/components/worker-diagram/dual-filter/index-test.js +++ b/ui/admin/tests/integration/components/worker-diagram/dual-filter/index-test.js @@ -17,12 +17,10 @@ module( let featuresService; const targetWorkerFilterIngress = 'target-worker-filters-v2-ingress'; - const targetWorkerFilterHCP = 'target-worker-filters-v2-hcp'; hooks.beforeEach(function () { featuresService = this.owner.lookup('service:features'); featuresService.enable(targetWorkerFilterIngress); - featuresService.disable(targetWorkerFilterHCP); }); test('it renders the correct diagram when egress and ingress filter is false', async function (assert) { diff --git a/ui/admin/tests/integration/components/worker-diagram/index-test.js b/ui/admin/tests/integration/components/worker-diagram/index-test.js index 058c699ec..3310a90a8 100644 --- a/ui/admin/tests/integration/components/worker-diagram/index-test.js +++ b/ui/admin/tests/integration/components/worker-diagram/index-test.js @@ -19,31 +19,32 @@ module('Integration | Component | worker-diagram/index', function (hooks) { test('it renders a single filter diagram', async function (assert) { featuresService = this.owner.lookup('service:features'); - featuresService.disable(targetWorkerFilterIngress); - featuresService.disable(targetWorkerFilterHCP); - assert.expect(1); + assert.expect(3); await render(hbs``); - + assert.false(featuresService.isEnabled(targetWorkerFilterIngress)); + assert.false(featuresService.isEnabled(targetWorkerFilterHCP)); assert.dom('[data-test-single-filter-egress-off]').isVisible(); }); test('it renders a dual filter diagram when `target-worker-filters-v2-ingress` is enabled', async function (assert) { featuresService = this.owner.lookup('service:features'); featuresService.enable(targetWorkerFilterIngress); - featuresService.disable(targetWorkerFilterHCP); - assert.expect(1); + assert.expect(3); + assert.true(featuresService.isEnabled(targetWorkerFilterIngress)); + assert.false(featuresService.isEnabled(targetWorkerFilterHCP)); await render(hbs``); assert.dom('[data-test-dual-filter-egress-off-ingress-off]').isVisible(); }); - test('it renders a HCP dual filter diagram when `target-worker-filters-v2-hcp` is enabled', async function (assert) { + test('it renders an HCP dual filter diagram when `target-worker-filters-v2-hcp` is enabled', async function (assert) { featuresService = this.owner.lookup('service:features'); featuresService.enable(targetWorkerFilterIngress); featuresService.enable(targetWorkerFilterHCP); - assert.expect(1); + assert.expect(3); await render(hbs``); - + assert.true(featuresService.isEnabled(targetWorkerFilterIngress)); + assert.true(featuresService.isEnabled(targetWorkerFilterHCP)); assert .dom('[data-test-dual-filter-hcp-egress-off-ingress-off]') .isVisible(); diff --git a/ui/admin/tests/unit/abilities/credential-library-test.js b/ui/admin/tests/unit/abilities/credential-library-test.js index b1252507f..0765bb72f 100644 --- a/ui/admin/tests/unit/abilities/credential-library-test.js +++ b/ui/admin/tests/unit/abilities/credential-library-test.js @@ -17,11 +17,11 @@ module('Unit | Abilities | credential-library', function (hooks) { hooks.beforeEach(function () { features = this.owner.lookup('service:features'); - features.enable('ssh-target'); }); test('can read credential library type when authorized and feature is enabled', function (assert) { assert.expect(2); + features.enable('ssh-target'); const canService = this.owner.lookup('service:can'); const store = this.owner.lookup('service:store'); const credentialLibrary = store.createRecord('credential-library', { @@ -35,6 +35,7 @@ module('Unit | Abilities | credential-library', function (hooks) { test('cannot read credential library type when unauthorized and feature is enabled', function (assert) { assert.expect(2); + features.enable('ssh-target'); const canService = this.owner.lookup('service:can'); const store = this.owner.lookup('service:store'); const credentialLibrary = store.createRecord('credential-library', { @@ -47,30 +48,30 @@ module('Unit | Abilities | credential-library', function (hooks) { }); test('cannot read credential library type when unauthorized and feature is disabled', function (assert) { - assert.expect(2); + assert.expect(3); const canService = this.owner.lookup('service:can'); const store = this.owner.lookup('service:store'); const featuresService = this.owner.lookup('service:features'); - featuresService.disable('ssh-target'); const credentialLibrary = store.createRecord('credential-library', { authorized_actions: [], type: TYPE_CREDENTIAL_LIBRARY_VAULT_SSH_CERTIFICATE, }); + assert.false(featuresService.isEnabled('ssh-target')); assert.false(canService.can('read credential-library', credentialLibrary)); credentialLibrary.type = TYPE_CREDENTIAL_LIBRARY_VAULT_GENERIC; assert.false(canService.can('read credential-library', credentialLibrary)); }); test('can read vault-generic but not vault-ssh-certificate when authorized and feature is disabled', function (assert) { - assert.expect(2); + assert.expect(3); const canService = this.owner.lookup('service:can'); const store = this.owner.lookup('service:store'); const featuresService = this.owner.lookup('service:features'); - featuresService.disable('ssh-target'); const credentialLibrary = store.createRecord('credential-library', { authorized_actions: ['read'], type: TYPE_CREDENTIAL_LIBRARY_VAULT_SSH_CERTIFICATE, }); + assert.false(featuresService.isEnabled('ssh-target')); assert.false(canService.can('read credential-library', credentialLibrary)); credentialLibrary.type = TYPE_CREDENTIAL_LIBRARY_VAULT_GENERIC; assert.true(canService.can('read credential-library', credentialLibrary)); diff --git a/ui/admin/tests/unit/abilities/credential-test.js b/ui/admin/tests/unit/abilities/credential-test.js index 8b19f5196..b60d95a7c 100644 --- a/ui/admin/tests/unit/abilities/credential-test.js +++ b/ui/admin/tests/unit/abilities/credential-test.js @@ -9,16 +9,16 @@ import { setupTest } from 'ember-qunit'; module('Unit | Abilities | credential', function (hooks) { setupTest(hooks); - let features; + let featuresService; hooks.beforeEach(function () { // Enable json-credentials feature by default - features = this.owner.lookup('service:features'); - features.enable('json-credentials'); + featuresService = this.owner.lookup('service:features'); }); test('can read credentials, including JSON credentials, when authorized and json-credentials feature is enabled', function (assert) { assert.expect(3); + featuresService.enable('json-credentials'); const service = this.owner.lookup('service:can'); const store = this.owner.lookup('service:store'); const credential = store.createRecord('credential', { @@ -34,6 +34,7 @@ module('Unit | Abilities | credential', function (hooks) { test('cannot read credentials, including JSON credentials, when unauthorized and json-credentials feature is enabled', function (assert) { assert.expect(3); + featuresService.enable('json-credentials'); const service = this.owner.lookup('service:can'); const store = this.owner.lookup('service:store'); const credential = store.createRecord('credential', { @@ -48,15 +49,14 @@ module('Unit | Abilities | credential', function (hooks) { }); test('cannot read credentials, including JSON credentials, when unauthorized and json-credentials feature is disabled', function (assert) { - assert.expect(3); + assert.expect(4); const service = this.owner.lookup('service:can'); - const featuresService = this.owner.lookup('service:features'); - featuresService.disable('json-credentials'); const store = this.owner.lookup('service:store'); const credential = store.createRecord('credential', { authorized_actions: [], type: 'json', }); + assert.false(featuresService.isEnabled('json-credentials')); assert.false(service.can('read credential', credential)); credential.type = 'username_password'; assert.false(service.can('read credential', credential)); @@ -65,14 +65,14 @@ module('Unit | Abilities | credential', function (hooks) { }); test('can read credentials, excepting JSON credentials, when authorized and json-credentials feature is disabled', function (assert) { - assert.expect(3); - features.disable('json-credentials'); + assert.expect(4); const service = this.owner.lookup('service:can'); const store = this.owner.lookup('service:store'); const credential = store.createRecord('credential', { authorized_actions: ['read'], type: 'json', }); + assert.false(featuresService.isEnabled('json-credentials')); assert.false(service.can('read credential', credential)); credential.type = 'username_password'; assert.true(service.can('read credential', credential)); diff --git a/ui/admin/tests/unit/instance-initializers/feature-edition-test.js b/ui/admin/tests/unit/instance-initializers/feature-edition-test.js index 1a917be63..c04d8fee3 100644 --- a/ui/admin/tests/unit/instance-initializers/feature-edition-test.js +++ b/ui/admin/tests/unit/instance-initializers/feature-edition-test.js @@ -1,3 +1,8 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + import Application from '@ember/application'; import config from 'admin/config/environment'; diff --git a/ui/admin/tests/unit/services/feature-edition-test.js b/ui/admin/tests/unit/services/feature-edition-test.js index 9b922a472..79bce781a 100644 --- a/ui/admin/tests/unit/services/feature-edition-test.js +++ b/ui/admin/tests/unit/services/feature-edition-test.js @@ -1,3 +1,8 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + import { module, test } from 'qunit'; import { setupTest } from 'admin/tests/helpers'; diff --git a/ui/desktop/package.json b/ui/desktop/package.json old mode 100755 new mode 100644 index a98a083fe..1146e1d1a --- a/ui/desktop/package.json +++ b/ui/desktop/package.json @@ -117,7 +117,7 @@ "stylelint": "^14.14.0", "stylelint-config-prettier-scss": "^0.0.1", "stylelint-config-standard-scss": "^7.0.1", - "webpack": "^5.72.1" + "webpack": "^5.76.0" }, "engines": { "node": "12.* || 14.* || 16.*" diff --git a/yarn.lock b/yarn.lock index c8d99277f..b6744f3e6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7316,14 +7316,6 @@ dependencies: "@types/node" "*" -"@types/eslint-scope@^3.7.0": - version "3.7.1" - resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.1.tgz#8dc390a7b4f9dd9f1284629efce982e41612116e" - integrity sha512-SCFeogqiptms4Fg29WpOTk5nHIzfpKCemSN63ksBQYKTcXoJEmJagV+DhVmbapZzY4/5YaOV1nZwrsU79fFm1g== - dependencies: - "@types/eslint" "*" - "@types/estree" "*" - "@types/eslint-scope@^3.7.3": version "3.7.4" resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.4.tgz#37fc1223f0786c39627068a12e94d6e6fc61de16" @@ -7348,12 +7340,7 @@ "@types/estree" "*" "@types/json-schema" "*" -"@types/estree@*", "@types/estree@^0.0.50": - version "0.0.50" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.50.tgz#1e0caa9364d3fccd2931c3ed96fdbeaa5d4cca83" - integrity sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw== - -"@types/estree@^0.0.51": +"@types/estree@*", "@types/estree@^0.0.51": version "0.0.51" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== @@ -8133,26 +8120,11 @@ acorn@^7.1.1, acorn@^7.4.0, acorn@^7.4.1: resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -acorn@^8.2.4: - version "8.4.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.4.1.tgz#56c36251fc7cabc7096adc18f05afe814321a28c" - integrity sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA== - -acorn@^8.4.1: - version "8.5.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.5.0.tgz#4512ccb99b3698c752591e9bb4472e38ad43cee2" - integrity sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q== - -acorn@^8.5.0: +acorn@^8.2.4, acorn@^8.5.0, acorn@^8.7.1: version "8.8.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8" integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w== -acorn@^8.7.1: - version "8.7.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.1.tgz#0197122c843d1bf6d0a5e83220a788f278f63c30" - integrity sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A== - address@1.1.2, address@^1.0.1: version "1.1.2" resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6" @@ -8265,7 +8237,7 @@ ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.2, ajv@^6.12.3, ajv@^6.12.4, ajv json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ajv@^8.0.0, ajv@^8.8.0: +ajv@^8.0.0, ajv@^8.0.1, ajv@^8.8.0: version "8.11.0" resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.11.0.tgz#977e91dd96ca669f54a11e23e378e33b884a565f" integrity sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg== @@ -8275,16 +8247,6 @@ ajv@^8.0.0, ajv@^8.8.0: require-from-string "^2.0.2" uri-js "^4.2.2" -ajv@^8.0.1: - version "8.6.2" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.6.2.tgz#2fb45e0e5fcbc0813326c1c3da535d1881bb0571" - integrity sha512-9807RlWAgT564wT+DjeyU5OFMPjmzxVobvDFmNAhY+5zD6A2ly3jDp6sgnfyDtlIQ+7H97oc/DGCzzfu9rjw9w== - dependencies: - fast-deep-equal "^3.1.1" - json-schema-traverse "^1.0.0" - require-from-string "^2.0.2" - uri-js "^4.2.2" - amd-name-resolver@^1.2.0, amd-name-resolver@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/amd-name-resolver/-/amd-name-resolver-1.3.1.tgz#ffe71c683c6e7191fc4ae1bb3aaed15abea135d9" @@ -9567,7 +9529,7 @@ braces@^2.3.1, braces@^2.3.2: split-string "^3.0.2" to-regex "^3.0.1" -braces@^3.0.1, braces@^3.0.2, braces@~3.0.2: +braces@^3.0.2, 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== @@ -10551,9 +10513,9 @@ caniuse-api@^3.0.0: lodash.uniq "^4.5.0" caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001157, caniuse-lite@^1.0.30001449: - version "1.0.30001473" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001473.tgz#3859898b3cab65fc8905bb923df36ad35058153c" - integrity sha512-ewDad7+D2vlyy+E4UJuVfiBsU69IL+8oVmTuZnH5Q6CIUbxNfI50uVpRHbUPDD6SUaN2o0Lh4DhTrvLG/Tn1yg== + version "1.0.30001466" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001466.tgz#c1e6197c540392e09709ecaa9e3e403428c53375" + integrity sha512-ewtFBSfWjEmxUgNBSZItFSmVtvk9zkwkl1OfRZlKA8slltRN+/C/tuGVrF9styXkN36Yu3+SeJ1qkXxDEyNZ5w== capture-exit@^2.0.0: version "2.0.0" @@ -14166,7 +14128,7 @@ enhanced-resolve@^4.0.0, enhanced-resolve@^4.5.0: memory-fs "^0.5.0" tapable "^1.0.0" -enhanced-resolve@^5.10.0, enhanced-resolve@^5.9.3: +enhanced-resolve@^5.10.0: version "5.10.0" resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz#0dc579c3bb2a1032e357ac45b8f3a6f3ad4fb1e6" integrity sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ== @@ -14174,14 +14136,6 @@ enhanced-resolve@^5.10.0, enhanced-resolve@^5.9.3: graceful-fs "^4.2.4" tapable "^2.2.0" -enhanced-resolve@^5.8.3: - version "5.8.3" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz#6d552d465cce0423f5b3d718511ea53826a7b2f0" - integrity sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA== - dependencies: - graceful-fs "^4.2.4" - tapable "^2.2.0" - enquirer@^2.3.5: version "2.3.6" resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" @@ -16411,17 +16365,7 @@ got@^11.7.0, got@^11.8.2, got@^11.8.5, got@^6.7.1, got@^9.6.0: p-cancelable "^2.0.0" responselike "^2.0.0" -graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.4: - version "4.2.8" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a" - integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg== - -graceful-fs@^4.2.10, graceful-fs@^4.2.2: - 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== - -graceful-fs@^4.2.6, graceful-fs@^4.2.9: +graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.10, graceful-fs@^4.2.2, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: version "4.2.10" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== @@ -20257,15 +20201,7 @@ micromatch@^3.1.10, micromatch@^3.1.4: snapdragon "^0.8.1" to-regex "^3.0.2" -micromatch@^4.0.2, micromatch@^4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" - integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== - dependencies: - braces "^3.0.1" - picomatch "^2.2.3" - -micromatch@^4.0.5: +micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5: version "4.0.5" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== @@ -20281,36 +20217,17 @@ miller-rabin@^4.0.0: bn.js "^4.0.0" brorand "^1.0.1" -mime-db@1.49.0, "mime-db@>= 1.43.0 < 2": - version "1.49.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.49.0.tgz#f3dfde60c99e9cf3bc9701d687778f537001cbed" - integrity sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA== - -mime-db@1.50.0: - version "1.50.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.50.0.tgz#abd4ac94e98d3c0e185016c67ab45d5fde40c11f" - integrity sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A== - 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.18, mime-types@^2.1.26, mime-types@^2.1.27: - version "2.1.32" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.32.tgz#1d00e89e7de7fe02008db61001d9e02852670fd5" - integrity sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A== - dependencies: - mime-db "1.49.0" +"mime-db@>= 1.43.0 < 2": + version "1.49.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.49.0.tgz#f3dfde60c99e9cf3bc9701d687778f537001cbed" + integrity sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA== -mime-types@^2.1.25: - version "2.1.33" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.33.tgz#1fa12a904472fafd068e48d9e8401f74d3f70edb" - integrity sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g== - dependencies: - mime-db "1.50.0" - -mime-types@~2.1.19, mime-types@~2.1.24, mime-types@~2.1.34: +mime-types@^2.1.12, mime-types@^2.1.18, mime-types@^2.1.25, mime-types@^2.1.26, mime-types@^2.1.27, 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== @@ -20561,14 +20478,7 @@ mkdirp@^0.3.5: resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.3.5.tgz#de3e5f8961c88c787ee1368df849ac4413eca8d7" integrity sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc= -mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.4, mkdirp@^0.5.5, mkdirp@~0.5.1: - version "0.5.5" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" - integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== - dependencies: - minimist "^1.2.5" - -mkdirp@^0.5.6, mkdirp@~0.5.0: +mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.4, mkdirp@^0.5.5, mkdirp@^0.5.6, mkdirp@~0.5.0, mkdirp@~0.5.1: version "0.5.6" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== @@ -25738,9 +25648,9 @@ terser-webpack-plugin@^5.1.3: terser "^5.7.2" terser@^4.1.2, terser@^4.6.3, terser@^5.14.2, terser@^5.3.0, terser@^5.3.4, terser@^5.7.2: - version "5.16.8" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.16.8.tgz#ccde583dabe71df3f4ed02b65eb6532e0fae15d5" - integrity sha512-QI5g1E/ef7d+PsDifb+a6nnVgC4F22Bg6T0xrBrz6iloVB4PUkkunp6V8nzoOOZJIzjWVdAGqCdlKlhLq/TbIA== + version "5.16.6" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.16.6.tgz#f6c7a14a378ee0630fbe3ac8d1f41b4681109533" + integrity sha512-IBZ+ZQIA9sMaXmRZCUMDjNH0D5AQQfdn4WUjHL0+1lF4TP1IHRJbrhb6fNaXWikrYQTSkb7SLxkeXAiy1p7mbg== dependencies: "@jridgewell/source-map" "^0.3.2" acorn "^8.5.0" @@ -26940,15 +26850,7 @@ watchpack@^1.7.4: chokidar "^3.4.1" watchpack-chokidar2 "^2.0.1" -watchpack@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.2.0.tgz#47d78f5415fe550ecd740f99fe2882323a58b1ce" - integrity sha512-up4YAn/XHgZHIxFBVCdlMiWDj6WaLKpwVeGQk2I5thdYxF/KmF0aaz6TfJZ/hfl1h/XlcDr7k1KH7ThDagpFaA== - dependencies: - glob-to-regexp "^0.4.1" - graceful-fs "^4.1.2" - -watchpack@^2.3.1, watchpack@^2.4.0: +watchpack@^2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d" integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg== @@ -27025,11 +26927,6 @@ webpack-sources@^1.4.0, webpack-sources@^1.4.1, webpack-sources@^1.4.3: source-list-map "^2.0.0" source-map "~0.6.1" -webpack-sources@^3.2.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.1.tgz#251a7d9720d75ada1469ca07dbb62f3641a05b6d" - integrity sha512-t6BMVLQ0AkjBOoRTZgqrWm7xbXMBzD+XDq2EZ96+vMfn3qKgsvdXZhbPZ4ElUOpdv4u+iiGe+w3+J75iy/bYGA== - webpack-sources@^3.2.3: version "3.2.3" resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" @@ -27071,40 +26968,10 @@ webpack@4, webpack@^4.43.0: watchpack "^1.7.4" webpack-sources "^1.4.1" -webpack@^5.59.1: - version "5.59.1" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.59.1.tgz#60c77e9aad796252153d4d7ab6b2d4c11f0e548c" - integrity sha512-I01IQV9K96FlpXX3V0L4nvd7gb0r7thfuu1IfT2P4uOHOA77nKARAKDYGe/tScSHKnffNIyQhLC8kRXzY4KEHQ== - dependencies: - "@types/eslint-scope" "^3.7.0" - "@types/estree" "^0.0.50" - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/wasm-edit" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" - acorn "^8.4.1" - acorn-import-assertions "^1.7.6" - browserslist "^4.14.5" - chrome-trace-event "^1.0.2" - enhanced-resolve "^5.8.3" - es-module-lexer "^0.9.0" - eslint-scope "5.1.1" - events "^3.2.0" - glob-to-regexp "^0.4.1" - graceful-fs "^4.2.4" - json-parse-better-errors "^1.0.2" - loader-runner "^4.2.0" - mime-types "^2.1.27" - neo-async "^2.6.2" - schema-utils "^3.1.0" - tapable "^2.1.1" - terser-webpack-plugin "^5.1.3" - watchpack "^2.2.0" - webpack-sources "^3.2.0" - -webpack@^5.72.1: - version "5.75.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.75.0.tgz#1e440468647b2505860e94c9ff3e44d5b582c152" - integrity sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ== +webpack@^5.76.0: + version "5.76.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.76.0.tgz#f9fb9fb8c4a7dbdcd0d56a98e56b8a942ee2692c" + integrity sha512-l5sOdYBDunyf72HW8dF23rFtWq/7Zgvt/9ftMof71E/yUb1YLOBmTgA2K4vQthB3kotMrSj609txVE0dnr2fjA== dependencies: "@types/eslint-scope" "^3.7.3" "@types/estree" "^0.0.51" @@ -27131,36 +26998,6 @@ webpack@^5.72.1: watchpack "^2.4.0" webpack-sources "^3.2.3" -webpack@^5.73.0: - version "5.73.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.73.0.tgz#bbd17738f8a53ee5760ea2f59dce7f3431d35d38" - integrity sha512-svjudQRPPa0YiOYa2lM/Gacw0r6PvxptHj4FuEKQ2kX05ZLkjbVc5MnPs6its5j7IZljnIqSVo/OsY2X0IpHGA== - dependencies: - "@types/eslint-scope" "^3.7.3" - "@types/estree" "^0.0.51" - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/wasm-edit" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" - acorn "^8.4.1" - acorn-import-assertions "^1.7.6" - browserslist "^4.14.5" - chrome-trace-event "^1.0.2" - enhanced-resolve "^5.9.3" - es-module-lexer "^0.9.0" - eslint-scope "5.1.1" - events "^3.2.0" - glob-to-regexp "^0.4.1" - graceful-fs "^4.2.9" - json-parse-even-better-errors "^2.3.1" - loader-runner "^4.2.0" - mime-types "^2.1.27" - neo-async "^2.6.2" - schema-utils "^3.1.0" - tapable "^2.1.1" - terser-webpack-plugin "^5.1.3" - watchpack "^2.3.1" - webpack-sources "^3.2.3" - websocket-driver@>=0.5.1: version "0.7.4" resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760" From cdaab19d1f3fc57799627e504245aa084ff086b1 Mon Sep 17 00:00:00 2001 From: Cameron Perera Date: Tue, 4 Apr 2023 11:10:28 -0500 Subject: [PATCH 111/193] =?UTF-8?q?test:=20=F0=9F=92=8D=20fix=20flaky=20se?= =?UTF-8?q?ssion-recording=20player=20render=20test=20(#186)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../integration/components/session-recording/player-test.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ui/admin/tests/integration/components/session-recording/player-test.js b/ui/admin/tests/integration/components/session-recording/player-test.js index 9380b7e36..d7dd790f9 100644 --- a/ui/admin/tests/integration/components/session-recording/player-test.js +++ b/ui/admin/tests/integration/components/session-recording/player-test.js @@ -29,6 +29,7 @@ module('Integration | Component | session-recording/player', function (hooks) { `); - assert.dom(this.element).hasText('Back to channels --:----:--'); + assert.dom('.session-recording-player-header').hasText('Back to channels'); + assert.dom('.control-bar .timer').hasText('--:----:--'); }); }); From dc479d45b287c147874ffa71e10d0c4f819bb3cc Mon Sep 17 00:00:00 2001 From: Dharini Jeeva Date: Tue, 4 Apr 2023 09:44:25 -0700 Subject: [PATCH 112/193] =?UTF-8?q?chore:=20=F0=9F=A4=96=20yarn=20lock=20u?= =?UTF-8?q?p=20to=20date=20(#184)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Zhihe Li --- yarn.lock | 27 +++++---------------------- 1 file changed, 5 insertions(+), 22 deletions(-) diff --git a/yarn.lock b/yarn.lock index b6744f3e6..d737df48f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11867,7 +11867,7 @@ debug@^3.0.0, debug@^3.0.1, debug@^3.1.0, debug@^3.1.1, debug@^3.2.7: dependencies: ms "^2.1.1" -debuglog@*, debuglog@^1.0.1: +debuglog@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" integrity sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI= @@ -17051,7 +17051,7 @@ import-local@^3.0.2: pkg-dir "^4.2.0" resolve-cwd "^3.0.0" -imurmurhash@*, imurmurhash@^0.1.4: +imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= @@ -19187,11 +19187,6 @@ lodash._baseflatten@^3.0.0: lodash.isarguments "^3.0.0" lodash.isarray "^3.0.0" -lodash._baseindexof@*: - version "3.1.0" - resolved "https://registry.yarnpkg.com/lodash._baseindexof/-/lodash._baseindexof-3.1.0.tgz#fe52b53a1c6761e42618d654e4a25789ed61822c" - integrity sha512-bSYo8Pc/f0qAkr8fPJydpJjtrHiSynYfYBjtANIgXv5xEf1WlTC63dIDlgu0s9dmTvzRu1+JJTxcIAHe+sH0FQ== - lodash._baseuniq@~4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash._baseuniq/-/lodash._baseuniq-4.6.0.tgz#0ebb44e456814af7905c6212fa2c9b2d51b841e8" @@ -19200,16 +19195,11 @@ lodash._baseuniq@~4.6.0: lodash._createset "~4.0.0" lodash._root "~3.0.0" -lodash._bindcallback@*, lodash._bindcallback@^3.0.0: +lodash._bindcallback@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz#e531c27644cf8b57a99e17ed95b35c748789392e" integrity sha512-2wlI0JRAGX8WEf4Gm1p/mv/SZ+jLijpj0jyaE/AXeuQphzCgD8ZQW4oSpoN8JAopujOFGU3KMuq7qfHBWlGpjQ== -lodash._cacheindexof@*: - version "3.0.2" - resolved "https://registry.yarnpkg.com/lodash._cacheindexof/-/lodash._cacheindexof-3.0.2.tgz#3dc69ac82498d2ee5e3ce56091bafd2adc7bde92" - integrity sha512-S8dUjWr7SUT/X6TBIQ/OYoCHo1Stu1ZRy6uMUSKqzFnZp5G5RyQizSm6kvxD2Ewyy6AVfMg4AToeZzKfF99T5w== - lodash._createassigner@^3.0.0: version "3.1.1" resolved "https://registry.yarnpkg.com/lodash._createassigner/-/lodash._createassigner-3.1.1.tgz#838a5bae2fdaca63ac22dee8e19fa4e6d6970b11" @@ -19219,19 +19209,12 @@ lodash._createassigner@^3.0.0: lodash._isiterateecall "^3.0.0" lodash.restparam "^3.0.0" -lodash._createcache@*: - version "3.1.2" - resolved "https://registry.yarnpkg.com/lodash._createcache/-/lodash._createcache-3.1.2.tgz#56d6a064017625e79ebca6b8018e17440bdcf093" - integrity sha512-ev5SP+iFpZOugyab/DEUQxUeZP5qyciVTlgQ1f4Vlw7VUcCD8fVnyIqVUEIaoFH9zjAqdgi69KiofzvVmda/ZQ== - dependencies: - lodash._getnative "^3.0.0" - lodash._createset@~4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/lodash._createset/-/lodash._createset-4.0.3.tgz#0f4659fbb09d75194fa9e2b88a6644d363c9fe26" integrity sha512-GTkC6YMprrJZCYU3zcqZj+jkXkrXzq3IPBcF/fIPpNEAB4hZEtXU8zp/RwKOvZl43NUmwDbyRk3+ZTbeRdEBXA== -lodash._getnative@*, lodash._getnative@^3.0.0: +lodash._getnative@^3.0.0: version "3.9.1" resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" integrity sha512-RrL9VxMEPyDMHOd9uFbvMe8X55X16/cGM5IgOKgRElQZutpX89iS6vwl64duTV1/16w5JY7tuFNXqoekmh1EmA== @@ -19444,7 +19427,7 @@ lodash.pick@^4.4.0: resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3" integrity sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q== -lodash.restparam@*, lodash.restparam@^3.0.0: +lodash.restparam@^3.0.0: version "3.6.1" resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" integrity sha512-L4/arjjuq4noiUJpt3yS6KIKDtJwNe2fIYgMqyYYKoeIfV1iEqvPwhCx23o+R9dzouGihDAPN1dTIRWa7zk8tw== From 639d57f9279747b477f0ea799b3d20bbf185133b Mon Sep 17 00:00:00 2001 From: Dharini Jeeva Date: Tue, 4 Apr 2023 11:01:00 -0700 Subject: [PATCH 113/193] Icu 8704 enable session recording route model hook (#180) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 🎸 target session recording toggle --- addons/core/translations/resources/en-us.yaml | 5 +- .../form/enable-session-recording/index.js | 7 -- .../enable-session-recording/index.hbs | 44 ++++++------ .../target/enable-session-recording/index.js | 22 ++++++ .../target/enable-session-recording.js | 67 ++++++++++++++++++- .../target/enable-session-recording.hbs | 15 +++-- 6 files changed, 119 insertions(+), 41 deletions(-) delete mode 100644 ui/admin/app/components/form/enable-session-recording/index.js rename ui/admin/app/components/form/{ => target}/enable-session-recording/index.hbs (60%) create mode 100644 ui/admin/app/components/form/target/enable-session-recording/index.js diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml index a96c0e70f..b48cbc316 100644 --- a/addons/core/translations/resources/en-us.yaml +++ b/addons/core/translations/resources/en-us.yaml @@ -434,15 +434,12 @@ target: messages: add: title: Enable session recording for target - options: - 1: Storage Bucket 1 - 2: Storage Bucket 2 form: filter: label: Record sessions for this target select: label: AWS storage buckets - description: Description for storage buckets + description: Sessions will be recorded and stored in this location. Must use Amazon S3. brokered-credential-source: title: Brokered Credential title_plural: Brokered Credentials diff --git a/ui/admin/app/components/form/enable-session-recording/index.js b/ui/admin/app/components/form/enable-session-recording/index.js deleted file mode 100644 index 2ad3f2629..000000000 --- a/ui/admin/app/components/form/enable-session-recording/index.js +++ /dev/null @@ -1,7 +0,0 @@ -import Component from '@glimmer/component'; -import { tracked } from '@glimmer/tracking'; - -export default class FormEnableSessionRecordingIndexComponent extends Component { - // =attributes - @tracked toggleEnabled = true; -} diff --git a/ui/admin/app/components/form/enable-session-recording/index.hbs b/ui/admin/app/components/form/target/enable-session-recording/index.hbs similarity index 60% rename from ui/admin/app/components/form/enable-session-recording/index.hbs rename to ui/admin/app/components/form/target/enable-session-recording/index.hbs index 5b60064a4..b1234f746 100644 --- a/ui/admin/app/components/form/enable-session-recording/index.hbs +++ b/ui/admin/app/components/form/target/enable-session-recording/index.hbs @@ -1,50 +1,54 @@ - +
- {{t 'resources.target.enable-session-recording.form.filter.label' }} - {{#if this.toggleEnabled}} {{t 'resources.target.enable-session-recording.form.select.label' }} - - {{!TODO: add correct description for form-select}} {{t 'resources.target.enable-session-recording.form.select.description' }} - - {{!TODO: replace dummy data with storage-bucket name and remove uneeded translations}} - - + {{#each @storageBucketList as |bucket|}} + + {{/each}} - - {{#if @model.errors.name}} + {{#if @model.errors.storage_bucket_id}} - {{#each @model.errors.name as |error|}} + {{#each @model.errors.storage_bucket_id as |error|}} {{error.message}} {{/each}} @@ -55,14 +59,14 @@ - +
\ No newline at end of file diff --git a/ui/admin/app/components/form/target/enable-session-recording/index.js b/ui/admin/app/components/form/target/enable-session-recording/index.js new file mode 100644 index 000000000..f506eb89c --- /dev/null +++ b/ui/admin/app/components/form/target/enable-session-recording/index.js @@ -0,0 +1,22 @@ +import Component from '@glimmer/component'; +import { tracked } from '@glimmer/tracking'; +import { action } from '@ember/object'; + +export default class FormEnableSessionRecordingIndexComponent extends Component { + // =attributes + @tracked toggleEnabled = true; + + //actions + /** + * toggle to enable session recording for the target + */ + @action + toggleSessionRecording() { + this.toggleEnabled = !this.toggleEnabled; + } + + @action + selectStorageBucket({ target: { value: selectedStorageBucketID } }) { + this.args.model.storage_bucket_id = selectedStorageBucketID; + } +} diff --git a/ui/admin/app/routes/scopes/scope/targets/target/enable-session-recording.js b/ui/admin/app/routes/scopes/scope/targets/target/enable-session-recording.js index 5dd07dd22..3b2363fd0 100644 --- a/ui/admin/app/routes/scopes/scope/targets/target/enable-session-recording.js +++ b/ui/admin/app/routes/scopes/scope/targets/target/enable-session-recording.js @@ -1,9 +1,13 @@ import Route from '@ember/routing/route'; import { inject as service } from '@ember/service'; +import { action } from '@ember/object'; +import { loading } from 'ember-loading'; +import { notifySuccess, notifyError } from 'core/decorators/notify'; +import { set } from '@ember/object'; export default class ScopesScopeTargetsTargetEnableSessionRecordingRoute extends Route { // =services - + @service store; @service router; // =methods @@ -14,7 +18,64 @@ export default class ScopesScopeTargetsTargetEnableSessionRecordingRoute extends */ async model() { - // TODO: need model for storage_bucket as well - return this.modelFor('scopes.scope.targets.target'); + const target = this.modelFor('scopes.scope.targets.target'); + const { scopeID: scope_id } = this.modelFor('scopes.scope'); + + //fetch storage buckets from global scope + const globalScopeStorageBuckets = await this.store.query('storage-bucket', { + scope_id: 'global', + }); + + //fetch storage buckets from target's org scope + const orgScopeStorageBuckets = await this.store.query('storage-bucket', { + scope_id, + }); + + //merge results from both global and target's org scope + //into one list for the dropdown + const storageBucketList = [ + ...globalScopeStorageBuckets.toArray(), + ...orgScopeStorageBuckets.toArray(), + ]; + + return { + target, + storageBucketList, + }; + } + + // =actions + /** + * Add storage bucket to target if the toggle is enabled, else remove it + * @param {TargetModel} target + * @param {boolean} isToggleEnabled + */ + @action + @loading + @notifyError(({ message }) => message, { catch: true }) + @notifySuccess('notifications.add-success') + async save(target, isToggleEnabled) { + const { id } = target; + if (isToggleEnabled) { + await target.setStorageBucket(); + } else { + await target.removeStorageBucket(); + } + this.router.replaceWith('scopes.scope.targets.target', id); + } + + /** + * reset the selected storage bucket and redirect to target + * @param {TargetModel} target + */ + @action + cancel(target) { + const { id } = target; + const changedAttributes = target.changedAttributes(); + if (Object.keys(changedAttributes).length) { + const existingAttributes = changedAttributes?.['storage_bucket_id']?.[0]; + set(target, 'storage_bucket_id', existingAttributes); + } + this.router.replaceWith('scopes.scope.targets.target', id); } } diff --git a/ui/admin/app/templates/scopes/scope/targets/target/enable-session-recording.hbs b/ui/admin/app/templates/scopes/scope/targets/target/enable-session-recording.hbs index 81e7bad08..89818dfa6 100644 --- a/ui/admin/app/templates/scopes/scope/targets/target/enable-session-recording.hbs +++ b/ui/admin/app/templates/scopes/scope/targets/target/enable-session-recording.hbs @@ -9,21 +9,22 @@

{{t 'resources.target.enable-session-recording.messages.add.title'}}

- {{!TODO: add description for enabling session recording}} + - {{@model.id}} + {{@model.target.id}} - From 2c93c378c4dd2d7d5a6f164beea51e4bb4fd003f Mon Sep 17 00:00:00 2001 From: Dharini Jeeva Date: Tue, 4 Apr 2023 12:20:45 -0700 Subject: [PATCH 114/193] Fix feature flag session recording target (#187) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: πŸ€– wrap target session recording with feature flag * fix: πŸ› test * fix: πŸ› test * fix: πŸ› use ember truth helper --- .../templates/scopes/scope/targets/target/index.hbs | 8 ++++++-- ui/admin/tests/acceptance/targets/read-test.js | 11 +++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/ui/admin/app/templates/scopes/scope/targets/target/index.hbs b/ui/admin/app/templates/scopes/scope/targets/target/index.hbs index 212d49bbc..d76840a99 100644 --- a/ui/admin/app/templates/scopes/scope/targets/target/index.hbs +++ b/ui/admin/app/templates/scopes/scope/targets/target/index.hbs @@ -30,8 +30,12 @@ @cancel={{route-action 'cancel' @model}} /> - - {{#if (can 'setStorageBucket target' @model)}} + {{#if + (and + (can 'setStorageBucket target' @model) + (feature-flag 'session-recording') + ) + }}
diff --git a/ui/admin/tests/acceptance/targets/read-test.js b/ui/admin/tests/acceptance/targets/read-test.js index 7a9fdf1e4..a4367202c 100644 --- a/ui/admin/tests/acceptance/targets/read-test.js +++ b/ui/admin/tests/acceptance/targets/read-test.js @@ -195,7 +195,17 @@ module('Acceptance | targets | read', function (hooks) { .exists(); }); + test('cannot enable session recording for a target without proper authorization', async function (assert) { + assert.expect(2); + assert.false(featuresService.isEnabled('session-recording')); + + await visit(urls.sshTarget); + + assert.dom('.target-sidebar a').doesNotExist(); + }); + test('users can click on enable-recording button in target session-recording sidebar and it takes them to enable session recording', async function (assert) { + featuresService.enable('session-recording'); assert.expect(1); await visit(urls.sshTarget); @@ -205,6 +215,7 @@ module('Acceptance | targets | read', function (hooks) { }); test('users can click on settings icon in target session-recording sidebar and it takes them to enable session recording', async function (assert) { + featuresService.enable('session-recording'); assert.expect(1); await visit(urls.sshTarget); From 9fc4be7b61dbd2a9004d3e16c20c2d293f985971 Mon Sep 17 00:00:00 2001 From: Cameron Perera Date: Wed, 5 Apr 2023 10:02:19 -0500 Subject: [PATCH 115/193] =?UTF-8?q?refactor:=20=F0=9F=92=A1=20fix=20active?= =?UTF-8?q?=20link=20style=20issue=20with=20SR=20Player=20(#183)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: πŸ’‘ fix active link style issue with SR Player βœ… Closes: ICU-8774 * refactor: πŸ’‘ update player hds link to hds button and styles * refactor: πŸ’‘ add translation for "Back to channels" text * test: πŸ’ add Intl setup hook to player test --- addons/core/translations/resources/en-us.yaml | 2 ++ .../components/session-recording/player/index.hbs | 5 +++-- ui/admin/app/styles/app.scss | 12 +++++------- .../components/session-recording/player-test.js | 2 ++ 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml index b48cbc316..593e9db6a 100644 --- a/addons/core/translations/resources/en-us.yaml +++ b/addons/core/translations/resources/en-us.yaml @@ -232,6 +232,8 @@ session-recording: title: Channel title_plural: Channels details: Channel details + player: + back-navigation: Back to channels session: title: Session Playback form: diff --git a/ui/admin/app/components/session-recording/player/index.hbs b/ui/admin/app/components/session-recording/player/index.hbs index eed4493a5..bf97e2836 100644 --- a/ui/admin/app/components/session-recording/player/index.hbs +++ b/ui/admin/app/components/session-recording/player/index.hbs @@ -1,8 +1,9 @@
- diff --git a/ui/admin/app/styles/app.scss b/ui/admin/app/styles/app.scss index f2dba4b71..250f533e5 100644 --- a/ui/admin/app/styles/app.scss +++ b/ui/admin/app/styles/app.scss @@ -788,20 +788,18 @@ &-header { border-bottom: var(--player-divider) 0.125rem solid; - // override of standalone link styles to allow for + // override of button styles to allow for // static colors in light and dark mode a { color: var(--link-color); padding: 1rem; } - a:hover { + .hds-button--color-tertiary:hover, + .hds-button--color-tertiary:active { color: var(--link-color); - - /* stylelint-disable selector-class-pattern */ - .hds-link-standalone__text { - text-decoration-color: var(--link-color); - } + background-color: transparent; + border-color: transparent; } } diff --git a/ui/admin/tests/integration/components/session-recording/player-test.js b/ui/admin/tests/integration/components/session-recording/player-test.js index d7dd790f9..9f092b1b3 100644 --- a/ui/admin/tests/integration/components/session-recording/player-test.js +++ b/ui/admin/tests/integration/components/session-recording/player-test.js @@ -2,9 +2,11 @@ import { module, test } from 'qunit'; import { setupRenderingTest } from 'admin/tests/helpers'; import { render } from '@ember/test-helpers'; import { hbs } from 'ember-cli-htmlbars'; +import { setupIntl } from 'ember-intl/test-support'; module('Integration | Component | session-recording/player', function (hooks) { setupRenderingTest(hooks); + setupIntl(hooks); test('it renders', async function (assert) { const castConfig = { From 6a48c31d83e61a2838bd922c03f3eb1e59223dcf Mon Sep 17 00:00:00 2001 From: lisbet-alvarez <107949262+lisbet-alvarez@users.noreply.github.com> Date: Wed, 5 Apr 2023 10:49:15 -0700 Subject: [PATCH 116/193] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20add=20storage=20?= =?UTF-8?q?bucket=20card=20on=20ssh=20target=20(#163)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 🎸 storage bucket card on ssh target βœ… Closes: ICU-8631 * Update ui/admin/app/routes/scopes/scope/targets/target/index.js Co-authored-by: Zhihe Li --------- Co-authored-by: Zhihe Li --- addons/core/translations/resources/en-us.yaml | 6 ++--- .../components/form/storage-bucket/index.hbs | 2 +- .../scopes/scope/targets/target/index.js | 27 ++++++++++++++++++- .../scopes/scope/storage-buckets/index.hbs | 7 ++--- .../scopes/scope/targets/target/index.hbs | 2 +- .../tests/acceptance/targets/read-test.js | 21 ++++++++++++++- 6 files changed, 52 insertions(+), 13 deletions(-) diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml index 593e9db6a..c63974fe8 100644 --- a/addons/core/translations/resources/en-us.yaml +++ b/addons/core/translations/resources/en-us.yaml @@ -261,12 +261,10 @@ storage-bucket: titles: new: New Storage Bucket aws: AWS - global: Global - orgs: Orgs - types: - aws_s3: AWS S3 actions: delete: Delete Storage Bucket + types: + aws_s3: AWS S3 form: scope: label: Scope diff --git a/ui/admin/app/components/form/storage-bucket/index.hbs b/ui/admin/app/components/form/storage-bucket/index.hbs index 18018710f..aec210bde 100644 --- a/ui/admin/app/components/form/storage-bucket/index.hbs +++ b/ui/admin/app/components/form/storage-bucket/index.hbs @@ -11,7 +11,7 @@ as |form| > {{#if B.data.scopeModel.isGlobal}} - + {{else}} {{/if}} diff --git a/ui/admin/app/templates/scopes/scope/targets/target/index.hbs b/ui/admin/app/templates/scopes/scope/targets/target/index.hbs index d76840a99..fc3152c1a 100644 --- a/ui/admin/app/templates/scopes/scope/targets/target/index.hbs +++ b/ui/admin/app/templates/scopes/scope/targets/target/index.hbs @@ -56,7 +56,7 @@ diff --git a/ui/admin/tests/acceptance/targets/read-test.js b/ui/admin/tests/acceptance/targets/read-test.js index a4367202c..55b127369 100644 --- a/ui/admin/tests/acceptance/targets/read-test.js +++ b/ui/admin/tests/acceptance/targets/read-test.js @@ -21,7 +21,7 @@ module('Acceptance | targets | read', function (hooks) { setupMirage(hooks); let featuresService; - + const LINK_LIST_SELECTOR = '.link-list-item'; const instances = { scopes: { global: null, @@ -30,6 +30,7 @@ module('Acceptance | targets | read', function (hooks) { }, sshTarget: null, tcpTarget: null, + storageBucket: null, }; const urls = { globalScope: null, @@ -39,6 +40,7 @@ module('Acceptance | targets | read', function (hooks) { sshTarget: null, tcpTarget: null, enableSessionRecording: null, + storageBucket: null, }; hooks.beforeEach(function () { @@ -61,6 +63,9 @@ module('Acceptance | targets | read', function (hooks) { type: TYPE_TARGET_TCP, scope: instances.scopes.project, }); + instances.storageBucket = this.server.create('storage-bucket', { + scope: instances.scopes.global, + }); // Generate route URLs for resources urls.globalScope = `/scopes/global/scopes`; urls.orgScope = `/scopes/${instances.scopes.org.id}/scopes`; @@ -70,6 +75,7 @@ module('Acceptance | targets | read', function (hooks) { urls.tcpTarget = `${urls.targets}/${instances.tcpTarget.id}`; urls.unknownTarget = `${urls.targets}/foo`; urls.enableSessionRecording = `${urls.sshTarget}/enable-session-recording`; + urls.storageBucket = `${urls.projectScope}/storage-buckets/${instances.storageBucket.id}`; authenticateSession({}); }); @@ -214,6 +220,19 @@ module('Acceptance | targets | read', function (hooks) { assert.strictEqual(currentURL(), urls.enableSessionRecording); }); + test('users can click on associated storage bucket card on an ssh target', async function (assert) { + assert.expect(1); + featuresService.enable('ssh-target'); + featuresService.enable('session-recording'); + instances.sshTarget.update({ storageBucketId: instances.storageBucket.id }); + await visit(urls.targets); + + await click(`[href="${urls.sshTarget}"]`); + await click(LINK_LIST_SELECTOR); + + assert.strictEqual(currentURL(), urls.storageBucket); + }); + test('users can click on settings icon in target session-recording sidebar and it takes them to enable session recording', async function (assert) { featuresService.enable('session-recording'); assert.expect(1); From affcb420c7852ea89559579a42077c8a352e8c47 Mon Sep 17 00:00:00 2001 From: Randall Morey Date: Wed, 5 Apr 2023 16:55:08 -0700 Subject: [PATCH 117/193] =?UTF-8?q?chore:=20=F0=9F=A4=96=20add=20session-r?= =?UTF-8?q?ecording=20to=20licensedFeatures=20(#185)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ui/admin/config/features.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ui/admin/config/features.js b/ui/admin/config/features.js index 55bc8abbb..8338943fa 100644 --- a/ui/admin/config/features.js +++ b/ui/admin/config/features.js @@ -13,6 +13,7 @@ const devFeatures = { const licensedFeatures = { 'multi-hop-sessions': false, 'ssh-target': false, + 'session-recording': false, }; // Base edition declares available features, disabled by default. const baseEdition = { @@ -27,7 +28,6 @@ const baseEdition = { 'target-worker-filters-v2-hcp': false, 'target-network-address': false, 'vault-worker-filter': false, - 'session-recording': false, }; // Editions maps edition keys to their associated featuresets. const featureEditions = {}; @@ -43,7 +43,6 @@ featureEditions.enterprise = { ...featureEditions.oss, 'target-worker-filters-v2-ingress': true, 'vault-worker-filter': true, - 'session-recording': true, }; featureEditions.hcp = { ...featureEditions.enterprise, From 33af4cd7ea3439826cd7f6a44341f6525547cf94 Mon Sep 17 00:00:00 2001 From: lisbet-alvarez <107949262+lisbet-alvarez@users.noreply.github.com> Date: Thu, 6 Apr 2023 10:45:19 -0700 Subject: [PATCH 118/193] Icu 8801 update settings icon to link in target edit screen (#188) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: πŸ’‘ update settings icon to link in target edit screen * style: πŸ’„ whitespace βœ… Closes: ICU-8801 * test: πŸ’ remove unnecessary a11yAudit() check * test: πŸ’ fix test * refactor: πŸ’‘ fix translation * refactor: πŸ’‘ settings link shouldn't be visible under button --- addons/core/translations/resources/en-us.yaml | 1 + .../components/link-list-panel/item/index.hbs | 2 +- .../scopes/scope/storage-buckets/new.js | 2 +- ui/admin/app/styles/app.scss | 24 ++++--------------- .../scopes/scope/targets/target/index.hbs | 19 +++++++-------- .../tests/acceptance/targets/read-test.js | 22 +++++++++++------ .../components/link-list-panel/index-test.js | 2 +- 7 files changed, 32 insertions(+), 40 deletions(-) diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml index c63974fe8..4396ac2dc 100644 --- a/addons/core/translations/resources/en-us.yaml +++ b/addons/core/translations/resources/en-us.yaml @@ -408,6 +408,7 @@ target: sidebar: label: Session Recording help: Record SSH sessions on this target and save them to an Amazon S3 bucket. + link: Session Recording settings questions: delete-host-sources: title: Remove associated host sources? diff --git a/ui/admin/app/components/link-list-panel/item/index.hbs b/ui/admin/app/components/link-list-panel/item/index.hbs index 898cf91e3..c2eb34a6a 100644 --- a/ui/admin/app/components/link-list-panel/item/index.hbs +++ b/ui/admin/app/components/link-list-panel/item/index.hbs @@ -10,7 +10,7 @@
{{#if @route}} - + {{/if}} \ No newline at end of file diff --git a/ui/admin/app/routes/scopes/scope/storage-buckets/new.js b/ui/admin/app/routes/scopes/scope/storage-buckets/new.js index 8eeb7bce6..080365109 100644 --- a/ui/admin/app/routes/scopes/scope/storage-buckets/new.js +++ b/ui/admin/app/routes/scopes/scope/storage-buckets/new.js @@ -22,7 +22,7 @@ export default class ScopesScopeStorageBucketsNewRoute extends Route { * @return {StorageBucket} */ model() { - const scopeModel = this.modelFor('scopes.scope'); + const scopeModel = this.store.peekRecord('scope', 'global'); const record = this.store.createRecord('storage-bucket', { type: TYPE_STORAGE_BUCKET_PLUGIN, compositeType: TYPE_STORAGE_BUCKET_PLUGIN_AWS_S3, diff --git a/ui/admin/app/styles/app.scss b/ui/admin/app/styles/app.scss index 250f533e5..8068f309e 100644 --- a/ui/admin/app/styles/app.scss +++ b/ui/admin/app/styles/app.scss @@ -660,23 +660,15 @@ // target sidebar .target-sidebar { - .title-wrapper { - display: flex; - justify-content: space-between; - align-items: baseline; - - .hds-button { - box-shadow: none; - border: none; - background-color: transparent; - } - } - .description { color: var(--token-form-helper-text-color); font-weight: var(--token-typography-font-weight-normal); font-size: var(--token-typography-body-200-font-size); } + + .hds-link-standalone { + margin-top: 1rem; + } } .link-list-item { @@ -698,15 +690,9 @@ margin-bottom: 0.25rem; } - .flight-icon-chevron-right { + .flight-icon-arrow-right { color: var(--token-color-foreground-faint); } - - .hds-button { - box-shadow: none; - border: none; - background-color: transparent; - } } .key-value-list { diff --git a/ui/admin/app/templates/scopes/scope/targets/target/index.hbs b/ui/admin/app/templates/scopes/scope/targets/target/index.hbs index fc3152c1a..96d43b530 100644 --- a/ui/admin/app/templates/scopes/scope/targets/target/index.hbs +++ b/ui/admin/app/templates/scopes/scope/targets/target/index.hbs @@ -38,16 +38,7 @@ }}
-
-

{{t 'resources.target.form.sidebar.label'}}

- -
+

{{t 'resources.target.form.sidebar.label'}}

{{t 'resources.target.form.sidebar.help'}}

@@ -62,10 +53,16 @@ > + {{else}} Date: Fri, 7 Apr 2023 10:44:48 -0700 Subject: [PATCH 119/193] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20delete=20action?= =?UTF-8?q?=20for=20storage=20bucket=20(#191)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 🎸 delete action for storage bucket βœ… Closes: ICU-8229 --- addons/core/translations/resources/en-us.yaml | 4 + .../routes/scopes/scope/storage-buckets.js | 17 ++ .../scopes/scope/storage-buckets/index.hbs | 8 + .../acceptance/storage-buckets/delete-test.js | 163 ++++++++++++++++++ 4 files changed, 192 insertions(+) create mode 100644 ui/admin/tests/acceptance/storage-buckets/delete-test.js diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml index 4396ac2dc..0fd5949a4 100644 --- a/addons/core/translations/resources/en-us.yaml +++ b/addons/core/translations/resources/en-us.yaml @@ -290,6 +290,10 @@ storage-bucket: worker_filter: label: Worker filter help: Filter for Boundary workers that have network access to your storage. Boolean expression. + questions: + delete-storage-bucket: + title: Delete associated recordings? + message: This storage bucket may have session recordings associated with it. Deleting this storage bucket will delete these recordings when you save your changes. project: title: Project title_plural: Projects diff --git a/ui/admin/app/routes/scopes/scope/storage-buckets.js b/ui/admin/app/routes/scopes/scope/storage-buckets.js index 8185c65f8..eee836051 100644 --- a/ui/admin/app/routes/scopes/scope/storage-buckets.js +++ b/ui/admin/app/routes/scopes/scope/storage-buckets.js @@ -7,6 +7,7 @@ import Route from '@ember/routing/route'; import { inject as service } from '@ember/service'; import { action } from '@ember/object'; import { loading } from 'ember-loading'; +import { confirm } from 'core/decorators/confirm'; import { notifySuccess, notifyError } from 'core/decorators/notify'; export default class ScopesScopeStorageBucketsRoute extends Route { @@ -71,4 +72,20 @@ export default class ScopesScopeStorageBucketsRoute extends Route { storageBucket.rollbackAttributes(); if (isNew) this.router.transitionTo('scopes.scope.storage-buckets'); } + + /** + * Deletes the storage bucket. + * @param {StorageBucketModel} storageBucket + */ + @action + @loading + @confirm('resources.storage-bucket.questions.delete-storage-bucket.message', { + title: 'resources.storage-bucket.questions.delete-storage-bucket.title', + confirm: 'resources.storage-bucket.actions.delete', + }) + @notifyError(({ message }) => message, { catch: true }) + @notifySuccess('notifications.delete-success') + async delete(storageBucket) { + await storageBucket.destroyRecord(); + } } diff --git a/ui/admin/app/templates/scopes/scope/storage-buckets/index.hbs b/ui/admin/app/templates/scopes/scope/storage-buckets/index.hbs index f29ed6f90..4b3f46253 100644 --- a/ui/admin/app/templates/scopes/scope/storage-buckets/index.hbs +++ b/ui/admin/app/templates/scopes/scope/storage-buckets/index.hbs @@ -102,6 +102,14 @@ @model={{B.data.id}} @text={{t 'actions.edit'}} /> + {{#if (can 'delete model' B.data)}} + + + {{/if}} diff --git a/ui/admin/tests/acceptance/storage-buckets/delete-test.js b/ui/admin/tests/acceptance/storage-buckets/delete-test.js new file mode 100644 index 000000000..fac18ebe0 --- /dev/null +++ b/ui/admin/tests/acceptance/storage-buckets/delete-test.js @@ -0,0 +1,163 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import { module, test } from 'qunit'; +import { visit, click, currentURL } from '@ember/test-helpers'; +import { setupApplicationTest } from 'ember-qunit'; +import setupMirage from 'ember-cli-mirage/test-support/setup-mirage'; +import { Response } from 'miragejs'; +import { authenticateSession } from 'ember-simple-auth/test-support'; + +module('Acceptance | storage-buckets | delete', function (hooks) { + setupApplicationTest(hooks); + setupMirage(hooks); + + let intl; + let features; + let getStorageBucketCount; + + const DROPDOWN_BUTTON_SELECTOR = '.hds-dropdown-toggle-icon'; + const DELETE_DROPDOWN_SELECTOR = '.hds-dropdown-list [type="button"]'; + const DIALOG_DELETE_BTN_SELECTOR = '.rose-dialog .rose-button-primary'; + const DIALOG_CANCEL_BTN_SELECTOR = '.rose-dialog .rose-button-secondary'; + const DIALOG_MESSAGE_SELECTOR = '.rose-dialog-body'; + const DIALOG_TITLE_SELECTOR = '.rose-dialog-header'; + const NOTIFICATION_MSG_SELECTOR = '.rose-notification-body'; + const NOTIFICATION_MSG_TEXT = 'Deleted successfully.'; + + const instances = { + scopes: { + global: null, + org: null, + }, + storageBucket: null, + }; + + const urls = { + globalScope: null, + storageBuckets: null, + }; + + hooks.beforeEach(function () { + instances.scopes.global = this.server.create('scope', { id: 'global' }); + instances.scopes.org = this.server.create('scope', { + type: 'org', + scope: { id: 'global', type: 'global' }, + }); + instances.storageBucket = this.server.create('storage-bucket', { + scope: instances.scopes.global, + }); + urls.globalScope = `/scopes/global`; + urls.storageBuckets = `${urls.globalScope}/storage-buckets`; + getStorageBucketCount = () => + this.server.schema.storageBuckets.all().models.length; + + authenticateSession({}); + intl = this.owner.lookup('service:intl'); + features = this.owner.lookup('service:features'); + features.enable('session-recording'); + }); + + test('user can delete a storage bucket', async function (assert) { + assert.expect(2); + const storageBucketCount = getStorageBucketCount(); + await visit(urls.globalScope); + + await click(`[href="${urls.storageBuckets}"]`); + await click(DROPDOWN_BUTTON_SELECTOR); + await click(DELETE_DROPDOWN_SELECTOR); + + assert.strictEqual(currentURL(), urls.storageBuckets); + assert.strictEqual(getStorageBucketCount(), storageBucketCount - 1); + }); + + test('user can accept delete storage bucket via dialog', async function (assert) { + assert.expect(4); + const confirmService = this.owner.lookup('service:confirm'); + confirmService.enabled = true; + const storageBucketCount = getStorageBucketCount(); + await visit(urls.globalScope); + + await click(`[href="${urls.storageBuckets}"]`); + await click(DROPDOWN_BUTTON_SELECTOR); + await click(DELETE_DROPDOWN_SELECTOR); + + assert + .dom(DIALOG_DELETE_BTN_SELECTOR) + .hasText(intl.t('resources.storage-bucket.actions.delete')); + + await click(DIALOG_DELETE_BTN_SELECTOR); + + assert.dom(NOTIFICATION_MSG_SELECTOR).hasText(NOTIFICATION_MSG_TEXT); + assert.strictEqual(currentURL(), urls.storageBuckets); + assert.strictEqual(getStorageBucketCount(), storageBucketCount - 1); + }); + + test('user can cancel delete storage bucket via dialog', async function (assert) { + assert.expect(4); + const confirmService = this.owner.lookup('service:confirm'); + confirmService.enabled = true; + const storageBucketCount = getStorageBucketCount(); + await visit(urls.globalScope); + + await click(`[href="${urls.storageBuckets}"]`); + await click(DROPDOWN_BUTTON_SELECTOR); + await click(DELETE_DROPDOWN_SELECTOR); + + assert + .dom(DIALOG_TITLE_SELECTOR) + .hasText( + intl.t('resources.storage-bucket.questions.delete-storage-bucket.title') + ); + assert + .dom(DIALOG_MESSAGE_SELECTOR) + .hasText( + intl.t( + 'resources.storage-bucket.questions.delete-storage-bucket.message' + ) + ); + + await click(DIALOG_CANCEL_BTN_SELECTOR); + + assert.strictEqual(currentURL(), urls.storageBuckets); + assert.strictEqual(getStorageBucketCount(), storageBucketCount); + }); + + test('user cannot delete storage bucket without proper authorization', async function (assert) { + assert.expect(1); + await visit(urls.globalScope); + instances.storageBucket.authorized_actions = + instances.storageBucket.authorized_actions.filter( + (item) => item !== 'delete' + ); + + await click(`[href="${urls.storageBuckets}"]`); + await click(DROPDOWN_BUTTON_SELECTOR); + + assert.dom(DELETE_DROPDOWN_SELECTOR).doesNotExist(); + }); + + test('deleting a storage bucket which errors displays error messages', async function (assert) { + assert.expect(1); + await visit(urls.globalScope); + this.server.del('/storage-buckets/:id', () => { + return new Response( + 490, + {}, + { + status: 490, + code: 'error', + message: 'Oops.', + } + ); + }); + + await click(`[href="${urls.storageBuckets}"]`); + await click(DROPDOWN_BUTTON_SELECTOR); + await click(DELETE_DROPDOWN_SELECTOR); + + assert.dom(NOTIFICATION_MSG_SELECTOR).hasText('Oops.'); + }); +}); From 09796ac8a37b197aaaeca5793f1abf5b581c84e1 Mon Sep 17 00:00:00 2001 From: Dharini Jeeva Date: Fri, 7 Apr 2023 11:56:28 -0700 Subject: [PATCH 120/193] target session recording enablement acceptance test (#192) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * test: πŸ’ target session recording enablement tests --- .../target/enable-session-recording/index.hbs | 2 +- .../targets/enable-session-recording-test.js | 229 ++++++++++++++++++ .../tests/acceptance/targets/read-test.js | 59 +---- 3 files changed, 231 insertions(+), 59 deletions(-) create mode 100644 ui/admin/tests/acceptance/targets/enable-session-recording-test.js diff --git a/ui/admin/app/components/form/target/enable-session-recording/index.hbs b/ui/admin/app/components/form/target/enable-session-recording/index.hbs index b1234f746..ca8f0631c 100644 --- a/ui/admin/app/components/form/target/enable-session-recording/index.hbs +++ b/ui/admin/app/components/form/target/enable-session-recording/index.hbs @@ -21,7 +21,7 @@ @value={{@model.storage_bucket_id}} @type='text' @width='100%' - @name='storage_bucket_id' + name='storage_bucket_id' {{on 'change' this.selectStorageBucket}} as |F| > diff --git a/ui/admin/tests/acceptance/targets/enable-session-recording-test.js b/ui/admin/tests/acceptance/targets/enable-session-recording-test.js new file mode 100644 index 000000000..fee1bb1d1 --- /dev/null +++ b/ui/admin/tests/acceptance/targets/enable-session-recording-test.js @@ -0,0 +1,229 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import { module, test } from 'qunit'; +import { visit, find, click, currentURL } from '@ember/test-helpers'; +import { setupApplicationTest } from 'ember-qunit'; +import setupMirage from 'ember-cli-mirage/test-support/setup-mirage'; +import a11yAudit from 'ember-a11y-testing/test-support/audit'; +import { authenticateSession } from 'ember-simple-auth/test-support'; +import { TYPE_TARGET_SSH } from 'api/models/target'; +import select from '@ember/test-helpers/dom/select'; + +module('Acceptance | targets | enable session recording', function (hooks) { + setupApplicationTest(hooks); + setupMirage(hooks); + + let featuresService; + let storageBucketOne; + let storageBucketTwo; + + const SETTINGS_LINK_SELECTOR = '.target-sidebar .hds-link-standalone'; + const ENABLE_BUTTON_SELECTOR = '.target-sidebar .hds-button'; + const DROPDOWN_SELECTOR = '[name=storage_bucket_id]'; + const LINK_LIST_SELECTOR = '.link-list-item'; + const LINK_LIST_SELECTOR_ITEM_TEXT = '.link-list-item__text'; + const TOGGLE_SELECTOR = '[name=target-enable-session-recording]'; + const LINK_TO_NEW_STORAGE_BUCKET = + '.enable-session-recording-toggle .hds-link-standalone'; + const SAVE_BTN_SELECTOR = '.rose-form-actions .rose-button-primary'; + const CANCEL_BTN_SELECTOR = '.rose-form-actions .rose-button-secondary'; + + // Instances + const instances = { + scopes: { + global: null, + org: null, + }, + sessionRecording: null, + }; + + //URLs + const urls = { + globalScope: null, + orgScope: null, + projectScope: null, + targets: null, + target: null, + enableSessionRecording: null, + storageBuckets: null, + newStorageBucket: null, + }; + + hooks.beforeEach(function () { + featuresService = this.owner.lookup('service:features'); + // Generate resources + instances.scopes.global = this.server.create('scope', { id: 'global' }); + instances.scopes.org = this.server.create('scope', { + type: 'org', + scope: { id: 'global', type: 'global' }, + }); + instances.scopes.project = this.server.create('scope', { + type: 'project', + scope: { id: instances.scopes.org.id, type: 'org' }, + }); + + instances.target = this.server.create('target', { + scope: instances.scopes.project, + type: TYPE_TARGET_SSH, + }); + + instances.storageBucket = this.server.createList('storage-bucket', 2, { + scope: instances.scopes.global, + }); + + storageBucketOne = instances.storageBucket[0]; + storageBucketTwo = instances.storageBucket[1]; + + // Generate route URLs for resources + urls.globalScope = `/scopes/global/scopes`; + urls.orgScope = `/scopes/${instances.scopes.org.id}/scopes`; + urls.projectScope = `/scopes/${instances.scopes.project.id}`; + urls.targets = `${urls.projectScope}/targets`; + urls.target = `${urls.targets}/${instances.target.id}`; + urls.enableSessionRecording = `${urls.target}/enable-session-recording`; + urls.storageBuckets = `${urls.projectScope}/storage-buckets`; + urls.newStorageBucket = `${urls.storageBuckets}/new`; + urls.storageBucket = `${urls.storageBuckets}/${storageBucketOne.id}`; + + authenticateSession({}); + }); + + test('cannot enable session recording for a target without proper authorization', async function (assert) { + assert.expect(2); + assert.false(featuresService.isEnabled('session-recording')); + await visit(urls.target); + await a11yAudit(); + assert.dom('.target-sidebar a').doesNotExist(); + }); + + test('users can click on enable-recording button in target session-recording sidebar and it takes them to enable session recording', async function (assert) { + featuresService.enable('session-recording'); + assert.expect(2); + await visit(urls.target); + assert.dom(SETTINGS_LINK_SELECTOR).doesNotExist(); + await click(ENABLE_BUTTON_SELECTOR); + assert.strictEqual(currentURL(), urls.enableSessionRecording); + }); + + test('users can click on settings link in target session-recording sidebar and it takes them to enable session recording', async function (assert) { + featuresService.enable('session-recording'); + assert.expect(1); + instances.target.update({ + storageBucketId: storageBucketOne.id, + }); + await visit(urls.target); + await click(SETTINGS_LINK_SELECTOR); + assert.strictEqual(currentURL(), urls.enableSessionRecording); + }); + + test('users can click on associated storage bucket card on an ssh target', async function (assert) { + featuresService.enable('session-recording'); + assert.expect(1); + instances.target.update({ storageBucketId: storageBucketOne.id }); + await visit(urls.target); + await click(LINK_LIST_SELECTOR); + assert.strictEqual(currentURL(), urls.storageBucket); + }); + + test('toggle should be enabled and storage buckets list should be shown when enable session recording button is clicked', async function (assert) { + featuresService.enable('session-recording'); + assert.expect(3); + await visit(urls.target); + await click(ENABLE_BUTTON_SELECTOR); + assert.strictEqual(currentURL(), urls.enableSessionRecording); + assert.dom(TOGGLE_SELECTOR).isVisible(); + assert.dom(DROPDOWN_SELECTOR).isVisible(); + }); + + test('storage buckets list is hidden when toggle is disabled', async function (assert) { + featuresService.enable('session-recording'); + assert.expect(4); + await visit(urls.target); + await click(ENABLE_BUTTON_SELECTOR); + assert.strictEqual(currentURL(), urls.enableSessionRecording); + assert.dom(TOGGLE_SELECTOR).isVisible(); + assert.dom(DROPDOWN_SELECTOR).isVisible(); + await click(TOGGLE_SELECTOR); + assert.dom(DROPDOWN_SELECTOR).isNotVisible(); + }); + + test('link to add new storage bucket should be displayed and redirect to new storage buckets form', async function (assert) { + featuresService.enable('session-recording'); + assert.expect(3); + await visit(urls.target); + await click(ENABLE_BUTTON_SELECTOR); + assert.strictEqual(currentURL(), urls.enableSessionRecording); + assert.dom(LINK_TO_NEW_STORAGE_BUCKET).isVisible(); + await click(LINK_TO_NEW_STORAGE_BUCKET); + assert.strictEqual(currentURL(), urls.newStorageBucket); + }); + + test('retain last selected dropdown list value when the toggle is off', async function (assert) { + featuresService.enable('session-recording'); + assert.expect(3); + instances.target.update({ + storageBucketId: storageBucketOne.id, + }); + await visit(urls.target); + await click(SETTINGS_LINK_SELECTOR); + assert.strictEqual(currentURL(), urls.enableSessionRecording); + + const existingStorageBucketId = find(DROPDOWN_SELECTOR).value; + + //disable the toggle, dropdown should be hidden + await click(TOGGLE_SELECTOR); + assert.dom(DROPDOWN_SELECTOR).isNotVisible(); + + //enable the toggle now, + //it should have the previously selected storage_bucket_id + await click(TOGGLE_SELECTOR); + assert.dom(DROPDOWN_SELECTOR).hasValue(existingStorageBucketId); + }); + + test('can assign a storage bucket for the target', async function (assert) { + featuresService.enable('session-recording'); + assert.expect(5); + await visit(urls.target); + await click(ENABLE_BUTTON_SELECTOR); + assert.strictEqual(currentURL(), urls.enableSessionRecording); + assert.dom(DROPDOWN_SELECTOR).hasNoValue(); + + await select(DROPDOWN_SELECTOR, storageBucketTwo.id); + assert.dom(DROPDOWN_SELECTOR).hasValue(); + + await click(SAVE_BTN_SELECTOR); + + assert.strictEqual(currentURL(), urls.target); + + assert.strictEqual( + find(LINK_LIST_SELECTOR_ITEM_TEXT).textContent.trim(), + storageBucketTwo.name + ); + }); + + test('can cancel changes to an exisiting storage bucket selection', async function (assert) { + featuresService.enable('session-recording'); + assert.expect(3); + instances.target.update({ + storageBucketId: storageBucketOne.id, + }); + + await visit(urls.target); + await click(SETTINGS_LINK_SELECTOR); + assert.strictEqual(currentURL(), urls.enableSessionRecording); + + //update the storage bucket selection + await select(DROPDOWN_SELECTOR, storageBucketTwo); + + await click(CANCEL_BTN_SELECTOR); + assert.strictEqual(currentURL(), urls.target); + + assert.strictEqual( + find(LINK_LIST_SELECTOR_ITEM_TEXT).textContent.trim(), + storageBucketOne.name + ); + }); +}); diff --git a/ui/admin/tests/acceptance/targets/read-test.js b/ui/admin/tests/acceptance/targets/read-test.js index 8c0827cfe..c48f89e86 100644 --- a/ui/admin/tests/acceptance/targets/read-test.js +++ b/ui/admin/tests/acceptance/targets/read-test.js @@ -21,9 +21,6 @@ module('Acceptance | targets | read', function (hooks) { setupMirage(hooks); let featuresService; - const SETTINGS_LINK_SELECTOR = '.target-sidebar .hds-link-standalone'; - const ENABLE_BUTTON_SELECTOR = '.target-sidebar .hds-button'; - const LINK_LIST_SELECTOR = '.link-list-item'; const instances = { scopes: { @@ -33,7 +30,6 @@ module('Acceptance | targets | read', function (hooks) { }, sshTarget: null, tcpTarget: null, - storageBucket: null, }; const urls = { globalScope: null, @@ -42,8 +38,6 @@ module('Acceptance | targets | read', function (hooks) { targets: null, sshTarget: null, tcpTarget: null, - enableSessionRecording: null, - storageBucket: null, }; hooks.beforeEach(function () { @@ -66,9 +60,7 @@ module('Acceptance | targets | read', function (hooks) { type: TYPE_TARGET_TCP, scope: instances.scopes.project, }); - instances.storageBucket = this.server.create('storage-bucket', { - scope: instances.scopes.global, - }); + // Generate route URLs for resources urls.globalScope = `/scopes/global/scopes`; urls.orgScope = `/scopes/${instances.scopes.org.id}/scopes`; @@ -77,8 +69,6 @@ module('Acceptance | targets | read', function (hooks) { urls.sshTarget = `${urls.targets}/${instances.sshTarget.id}`; urls.tcpTarget = `${urls.targets}/${instances.tcpTarget.id}`; urls.unknownTarget = `${urls.targets}/foo`; - urls.enableSessionRecording = `${urls.sshTarget}/enable-session-recording`; - urls.storageBucket = `${urls.projectScope}/storage-buckets/${instances.storageBucket.id}`; authenticateSession({}); }); @@ -203,51 +193,4 @@ module('Acceptance | targets | read', function (hooks) { .dom(`[href="https://boundaryproject.io/help/admin-ui/targets"]`) .exists(); }); - - test('cannot enable session recording for a target without proper authorization', async function (assert) { - assert.expect(2); - assert.false(featuresService.isEnabled('session-recording')); - - await visit(urls.sshTarget); - - assert.dom(ENABLE_BUTTON_SELECTOR).doesNotExist(); - }); - - test('users can click on enable-recording button in target session-recording sidebar and it takes them to enable session recording', async function (assert) { - featuresService.enable('session-recording'); - assert.expect(2); - await visit(urls.sshTarget); - - assert.dom(SETTINGS_LINK_SELECTOR).doesNotExist(); - await click(ENABLE_BUTTON_SELECTOR); - - assert.strictEqual(currentURL(), urls.enableSessionRecording); - }); - - test('users can click on associated storage bucket card on an ssh target', async function (assert) { - assert.expect(1); - featuresService.enable('ssh-target'); - featuresService.enable('session-recording'); - instances.sshTarget.update({ storageBucketId: instances.storageBucket.id }); - await visit(urls.targets); - - await click(`[href="${urls.sshTarget}"]`); - await click(LINK_LIST_SELECTOR); - - assert.strictEqual(currentURL(), urls.storageBucket); - }); - - test('users can click on settings link in target session-recording sidebar and it takes them to enable session recording', async function (assert) { - featuresService.enable('session-recording'); - assert.expect(1); - featuresService.enable('ssh-target'); - featuresService.enable('session-recording'); - instances.sshTarget.update({ storageBucketId: instances.storageBucket.id }); - await visit(urls.targets); - - await click(`[href="${urls.sshTarget}"]`); - await click(SETTINGS_LINK_SELECTOR); - - assert.strictEqual(currentURL(), urls.enableSessionRecording); - }); }); From afd89bddb35efcc65c6deed79e887f6da674239a Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Corvo Date: Mon, 17 Apr 2023 12:49:08 -0700 Subject: [PATCH 121/193] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20Add=20MetadataLi?= =?UTF-8?q?st=20component=20(#193)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add MetadataList component and use of it within session-recordings βœ… Closes: ICU-8232 --- .../app/components/metadata-list/index.hbs | 3 + .../components/metadata-list/item/index.hbs | 4 ++ ui/admin/app/styles/app.scss | 18 +++++ .../channels-by-connection/channel.hbs | 51 ++++++-------- .../session-recording/index.hbs | 67 ++++++++++--------- .../components/metadata-list/index-test.js | 45 +++++++++++++ 6 files changed, 126 insertions(+), 62 deletions(-) create mode 100644 ui/admin/app/components/metadata-list/index.hbs create mode 100644 ui/admin/app/components/metadata-list/item/index.hbs create mode 100644 ui/admin/tests/integration/components/metadata-list/index-test.js diff --git a/ui/admin/app/components/metadata-list/index.hbs b/ui/admin/app/components/metadata-list/index.hbs new file mode 100644 index 000000000..1d4834598 --- /dev/null +++ b/ui/admin/app/components/metadata-list/index.hbs @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/ui/admin/app/components/metadata-list/item/index.hbs b/ui/admin/app/components/metadata-list/item/index.hbs new file mode 100644 index 000000000..05244849e --- /dev/null +++ b/ui/admin/app/components/metadata-list/item/index.hbs @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/ui/admin/app/styles/app.scss b/ui/admin/app/styles/app.scss index 8068f309e..d4ad4d21c 100644 --- a/ui/admin/app/styles/app.scss +++ b/ui/admin/app/styles/app.scss @@ -861,3 +861,21 @@ padding: 0.875rem 1rem; } } + +// Metadata List +.metadata-list { + display: flex; + flex-direction: row; + flex-wrap: wrap; + gap: 1rem; + + &.vertical { + flex-direction: column; + row-gap: 1rem; + } + + .metadata-list-item { + display: flex; + column-gap: 0.3rem; + } +} diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs index db8e1ca49..238948d80 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs @@ -24,35 +24,28 @@ {{! Channel details information }}

{{t 'resources.session-recording.channel.details'}}

- {{! Start time }} -

- - {{@model.channelRecording.start_time}} -

- - {{! Type }} -

- - {{@model.sessionRecording.type}} -

- - {{! Duration }} -

- - {{@model.channelRecording.duration}} -

- - {{! Bytes up }} -

- - {{format-bytes-size @model.channelRecording.bytes_up}} -

- - {{! Bytes down }} -

- - {{format-bytes-size @model.channelRecording.bytes_down}} -

+ + {{! Start time }} + + {{@model.sessionRecording.start_time}} + + {{! Type }} + + {{@model.sessionRecording.type}} + + {{! Duration }} + + {{format-time-duration @model.sessionRecording.duration}} + + {{! Bytes up }} + + {{format-bytes-size @model.sessionRecording.bytes_up}} + + {{! Bytes down }} + + {{format-bytes-size @model.sessionRecording.bytes_down}} + +
{{! Channel related information }} diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs index fb69f47f7..86efd4d5d 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs @@ -52,18 +52,22 @@ {{B.data.type}} - - {{format-bytes-size B.data.bytes_up}} - - {{format-bytes-size B.data.bytes_down}} - - - - {{format-time-duration B.data.duration}} - - + + {{! Bytes up }} + + {{format-bytes-size @model.sessionRecording.bytes_up}} + + {{! Bytes down }} + + {{format-bytes-size @model.sessionRecording.bytes_down}} + + {{! Duration }} + + {{format-time-duration + @model.sessionRecording.duration + }} + +

{{t 'resources.session-recording.details'}}

- {{! Start time }} -

- - {{@model.sessionRecording.start_time}} -

- {{! Duration }} -

- - {{@model.sessionRecording.duration}} -

- {{! Bytes up }} -

- - {{format-bytes-size @model.sessionRecording.bytes_up}} -

- - {{! Bytes down }} -

- - {{format-bytes-size @model.sessionRecording.bytes_down}} -

+ + {{! Start time }} + + {{@model.sessionRecording.start_time}} + + {{! Duration }} + + {{format-time-duration @model.sessionRecording.duration}} + + {{! Bytes up }} + + {{format-bytes-size @model.sessionRecording.bytes_up}} + + {{! Bytes down }} + + {{format-bytes-size @model.sessionRecording.bytes_down}} + +
{{! Related }}
diff --git a/ui/admin/tests/integration/components/metadata-list/index-test.js b/ui/admin/tests/integration/components/metadata-list/index-test.js new file mode 100644 index 000000000..91cb1d7c2 --- /dev/null +++ b/ui/admin/tests/integration/components/metadata-list/index-test.js @@ -0,0 +1,45 @@ +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'admin/tests/helpers'; +import { render } from '@ember/test-helpers'; +import { hbs } from 'ember-cli-htmlbars'; + +module('Integration | Component | metadata-list/item', function (hooks) { + setupRenderingTest(hooks); + + test('it renders horizontal (default) with icon, color and text', async function (assert) { + assert.expect(3); + await render(hbs` + + + Sample text + + + `); + + assert.dom('[data-test-icon="arrow-up"]').isVisible(); + assert.dom('li.metadata-list-item').hasClass('hds-foreground-success'); + assert.dom('li.metadata-list-item').hasText('Sample text'); + }); + + test('it renders vertical with icon, color and text', async function (assert) { + assert.expect(4); + await render(hbs` + + + Sample text 2 + + + `); + + assert.dom('ul.metadata-list').hasClass('vertical'); + assert.dom('[data-test-icon="arrow-down"]').isVisible(); + assert.dom('li.metadata-list-item').hasClass('hds-foreground-action'); + assert.dom('li.metadata-list-item').hasText('Sample text 2'); + }); +}); From c05e7002d84313fc049f10fefabfcac9713a3d59 Mon Sep 17 00:00:00 2001 From: Cameron Perera Date: Mon, 17 Apr 2023 17:48:41 -0500 Subject: [PATCH 122/193] =?UTF-8?q?refactor:=20=F0=9F=92=A1=20Update=20Asc?= =?UTF-8?q?iinema=20player=20control=20bar=20styles=20(#197)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: πŸ’‘ Update Asciinema player control bar styles βœ… Closes: ICU-8416 * refactor: πŸ’‘ remove rem from bottom set to 0 (zero) * style: πŸ’„ fix stylesheet linter issues --- ui/admin/app/styles/app.scss | 58 +++++++++++++++++++++++++++++++++--- 1 file changed, 54 insertions(+), 4 deletions(-) diff --git a/ui/admin/app/styles/app.scss b/ui/admin/app/styles/app.scss index d4ad4d21c..e8ecc9d19 100644 --- a/ui/admin/app/styles/app.scss +++ b/ui/admin/app/styles/app.scss @@ -766,7 +766,10 @@ .session-recording-player { --player-background-color: #252937; --player-divider: #656a761a; - --link-color: #fff; + --player-white: #fff; + --player-control-bar-buffer: #656a76; + --player-play-button: #1060ff; + --player-play-button-border: #0c56e9; background-color: var(--player-background-color); border-radius: 0.75rem; @@ -777,13 +780,13 @@ // override of button styles to allow for // static colors in light and dark mode a { - color: var(--link-color); + color: var(--player-white); padding: 1rem; } .hds-button--color-tertiary:hover, .hds-button--color-tertiary:active { - color: var(--link-color); + color: var(--player-white); background-color: transparent; border-color: transparent; } @@ -802,6 +805,11 @@ .asciinema-player { border-radius: 0.75rem; + + // hides large play icon overlay + .start-prompt { + z-index: -10; + } } .asciinema-player-wrapper { @@ -810,9 +818,51 @@ } .control-bar { - bottom: 0; + bottom: -3.625rem; background: var(--player-background-color); border-top: var(--player-divider) 0.125rem solid; + height: 3.625rem; + + .playback-button { + background: var(--player-play-button); + border: var(--player-play-button-border) 0.063rem solid; + border-radius: 0.313rem; + margin: 0.75rem; + padding: 0.625rem 1rem; + + .icon path { + fill: var(--player-white); + } + } + } + + .timer { + font-family: var(--token-typography-body-base-font-family); + font-size: var(--token-typography-body-base-font-size); + line-height: var(--token-typography-body-base-line-height); + color: var(--player-white); + position: relative; + top: 40%; + } + + .progressbar { + padding-top: 0.875rem; + + .bar .gutter { + background-color: var(--player-control-bar-buffer); + + span { + background-color: var(--player-white); + } + } + } + + .fullscreen-button { + padding-top: 1.5rem; + + .icon path { + fill: var(--player-white); + } } } } From ceefb0b31cf82752257a5bc575a32a323f1e21b1 Mon Sep 17 00:00:00 2001 From: Cameron Perera Date: Tue, 18 Apr 2023 10:54:01 -0500 Subject: [PATCH 123/193] =?UTF-8?q?refactor:=20=F0=9F=92=A1=20update=20sta?= =?UTF-8?q?rt=20prompt=20styles=20to=20display=20none=20(#200)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ui/admin/app/styles/app.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/admin/app/styles/app.scss b/ui/admin/app/styles/app.scss index e8ecc9d19..5a39244d9 100644 --- a/ui/admin/app/styles/app.scss +++ b/ui/admin/app/styles/app.scss @@ -808,7 +808,7 @@ // hides large play icon overlay .start-prompt { - z-index: -10; + display: none; } } From a48fd5d9f435b718a45b9bdc9ea215f52b146ee2 Mon Sep 17 00:00:00 2001 From: Cameron Perera Date: Tue, 18 Apr 2023 12:30:37 -0500 Subject: [PATCH 124/193] =?UTF-8?q?refactor:=20=F0=9F=92=A1=20remove=20Typ?= =?UTF-8?q?e=20column=20from=20channel=20table=20(#201)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: πŸ’‘ remove Type column from channel table βœ… Closes: ICU-8772 * refactor: πŸ’‘ remove Type reference from Channel details sidebar * refactor: πŸ’‘ remove unused Type translation --- addons/core/translations/resources/en-us.yaml | 2 -- .../session-recording/channels-by-connection/channel.hbs | 4 ---- .../scope/session-recordings/session-recording/index.hbs | 8 -------- 3 files changed, 14 deletions(-) diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml index 0fd5949a4..af6208cbe 100644 --- a/addons/core/translations/resources/en-us.yaml +++ b/addons/core/translations/resources/en-us.yaml @@ -222,8 +222,6 @@ session-recording: form: channel: label: Channel - type: - label: Type summary: label: Summary channels-by-connection: diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs index 238948d80..ba86ba284 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs @@ -29,10 +29,6 @@ {{@model.sessionRecording.start_time}} - {{! Type }} - - {{@model.sessionRecording.type}} - {{! Duration }} {{format-time-duration @model.sessionRecording.duration}} diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs index 86efd4d5d..5a8f942b7 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs @@ -30,11 +30,6 @@ 'resources.session-recording.connection.form.channel.label' ) ) - (hash - label=(t - 'resources.session-recording.connection.form.type.label' - ) - ) (hash label=(t 'resources.session-recording.connection.form.summary.label' @@ -48,9 +43,6 @@ {{B.data.id}} - - {{B.data.type}} - {{! Bytes up }} From 40cddd829ed1cb1af237fb84b2dbe4670bcaedec Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Corvo Date: Tue, 18 Apr 2023 10:58:04 -0700 Subject: [PATCH 125/193] =?UTF-8?q?refactor:=20=F0=9F=92=A1=20Refactor=20l?= =?UTF-8?q?ink=20list=20panel=20(#199)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: πŸ’‘ Refactor link list panel --- .../components/link-list-panel/item/index.hbs | 25 +++++++++++++----- ui/admin/app/styles/app.scss | 12 ++++++--- .../targets/enable-session-recording-test.js | 2 +- .../components/link-list-panel/index-test.js | 26 +++++++++++++++++-- 4 files changed, 53 insertions(+), 12 deletions(-) diff --git a/ui/admin/app/components/link-list-panel/item/index.hbs b/ui/admin/app/components/link-list-panel/item/index.hbs index c2eb34a6a..a7d185b5f 100644 --- a/ui/admin/app/components/link-list-panel/item/index.hbs +++ b/ui/admin/app/components/link-list-panel/item/index.hbs @@ -1,16 +1,29 @@ -
  • - +
  • \ No newline at end of file diff --git a/ui/admin/app/styles/app.scss b/ui/admin/app/styles/app.scss index 5a39244d9..5782cc7b9 100644 --- a/ui/admin/app/styles/app.scss +++ b/ui/admin/app/styles/app.scss @@ -674,15 +674,21 @@ .link-list-item { display: flex; align-items: center; - justify-content: space-between; padding: 1rem; - text-decoration: none; + + a { + text-decoration: none; + align-items: center; + display: flex; + width: 100%; + } &__info { display: flex; + width: 100%; align-items: center; - gap: 0.75rem; margin-left: 0.25rem; + gap: 0.75rem; } &__text { diff --git a/ui/admin/tests/acceptance/targets/enable-session-recording-test.js b/ui/admin/tests/acceptance/targets/enable-session-recording-test.js index fee1bb1d1..e294c1c3c 100644 --- a/ui/admin/tests/acceptance/targets/enable-session-recording-test.js +++ b/ui/admin/tests/acceptance/targets/enable-session-recording-test.js @@ -23,7 +23,7 @@ module('Acceptance | targets | enable session recording', function (hooks) { const SETTINGS_LINK_SELECTOR = '.target-sidebar .hds-link-standalone'; const ENABLE_BUTTON_SELECTOR = '.target-sidebar .hds-button'; const DROPDOWN_SELECTOR = '[name=storage_bucket_id]'; - const LINK_LIST_SELECTOR = '.link-list-item'; + const LINK_LIST_SELECTOR = '.link-list-item > a'; const LINK_LIST_SELECTOR_ITEM_TEXT = '.link-list-item__text'; const TOGGLE_SELECTOR = '[name=target-enable-session-recording]'; const LINK_TO_NEW_STORAGE_BUCKET = diff --git a/ui/admin/tests/integration/components/link-list-panel/index-test.js b/ui/admin/tests/integration/components/link-list-panel/index-test.js index c43cadf00..f7133e2f2 100644 --- a/ui/admin/tests/integration/components/link-list-panel/index-test.js +++ b/ui/admin/tests/integration/components/link-list-panel/index-test.js @@ -6,8 +6,8 @@ import { hbs } from 'ember-cli-htmlbars'; module('Integration | Component | link-list-panel/index', function (hooks) { setupRenderingTest(hooks); - test('it renders with icons and text', async function (assert) { - assert.expect(5); + test('it renders with icons, text and yield content wrapped in a link, because @route is present', async function (assert) { + assert.expect(6); await render(hbs` @@ -24,5 +24,27 @@ module('Integration | Component | link-list-panel/index', function (hooks) { assert.dom('[data-test-icon="aws-color"]').isVisible(); assert.dom('.hds-badge__text').hasText('AWS S3'); assert.dom('.link-list-item__text').hasText('Storage Bucket'); + assert.dom('li.link-list-item > a').exists(); + }); + + test('it renders with icons, text and yield content WITHOUT a link, because @route is not present.', async function (assert) { + assert.expect(6); + await render(hbs` + + + + + + `); + + assert.dom('[data-test-icon="clock"]').isVisible(); + assert.dom('[data-test-icon="arrow-right"]').isNotVisible(); + assert.dom('[data-test-icon="aws-color"]').isVisible(); + assert.dom('.hds-badge__text').hasText('AWS S3'); + assert.dom('.link-list-item__text').hasText('Storage Bucket'); + assert.dom('li.link-list-item > a').doesNotExist(); }); }); From 61a3e17c5e47e07231457c0ebd6acfb6179e61a3 Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Corvo Date: Tue, 18 Apr 2023 13:00:18 -0700 Subject: [PATCH 126/193] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Use=20channel=20r?= =?UTF-8?q?ecording=20information=20(#202)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use channel recording information instead of session recording when on channel screen --- .../session-recording/channels-by-connection/channel.hbs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs index ba86ba284..102cb0625 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs @@ -27,19 +27,19 @@ {{! Start time }} - {{@model.sessionRecording.start_time}} + {{@model.channelRecording.start_time}} {{! Duration }} - {{format-time-duration @model.sessionRecording.duration}} + {{format-time-duration @model.channelRecording.duration}} {{! Bytes up }} - {{format-bytes-size @model.sessionRecording.bytes_up}} + {{format-bytes-size @model.channelRecording.bytes_up}} {{! Bytes down }} - {{format-bytes-size @model.sessionRecording.bytes_down}} + {{format-bytes-size @model.channelRecording.bytes_down}}
    From 4c9811739cb1c2897ed9ed172d4c8c15a6af9174 Mon Sep 17 00:00:00 2001 From: Zhihe Li Date: Wed, 19 Apr 2023 12:34:31 -0400 Subject: [PATCH 127/193] =?UTF-8?q?refactor:=20=F0=9F=92=A1=20Update=20lis?= =?UTF-8?q?t=20session=20recording=20API=20(#203)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: πŸ’‘ Update list session recording API --- addons/api/mirage/config.js | 13 ++++++++++++- .../app/routes/scopes/scope/session-recordings.js | 6 +++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/addons/api/mirage/config.js b/addons/api/mirage/config.js index 8a42d9662..25be61159 100644 --- a/addons/api/mirage/config.js +++ b/addons/api/mirage/config.js @@ -706,7 +706,18 @@ function routes() { ); // session recordings - this.get('/session-recordings'); + this.get( + '/session-recordings', + ( + { sessionRecordings }, + { queryParams: { scope_id: scopeId, recursive } } + ) => { + if (recursive && scopeId === 'global') { + return sessionRecordings.all(); + } + return sessionRecordings.where({ scopeId }); + } + ); this.get( '/session-recordings/:idMethod', async ({ sessionRecordings }, { params: { idMethod } }) => { diff --git a/ui/admin/app/routes/scopes/scope/session-recordings.js b/ui/admin/app/routes/scopes/scope/session-recordings.js index 9b121c822..e18a61020 100644 --- a/ui/admin/app/routes/scopes/scope/session-recordings.js +++ b/ui/admin/app/routes/scopes/scope/session-recordings.js @@ -26,7 +26,11 @@ export default class ScopesScopeSessionRecordingsRoute extends Route { const scope = this.modelFor('scopes.scope'); // if (this.can.can('list session-recording', scope, { collection: 'session-recordings' })) { const { id: scope_id } = scope; - const sessionRecordings = await this.store.findAll('session-recording'); + + const sessionRecordings = await this.store.query('session-recording', { + scope_id, + recursive: true, + }); const storageBuckets = await this.store.query('storage-bucket', { scope_id, recursive: true, From 85651d477668528bfd30eb2ca71304306c13c8c7 Mon Sep 17 00:00:00 2001 From: Cameron Perera Date: Wed, 19 Apr 2023 13:46:23 -0500 Subject: [PATCH 128/193] =?UTF-8?q?refactor:=20=F0=9F=92=A1=20sort=20conne?= =?UTF-8?q?ction=5Frecordings=20by=20start=5Ftime=20(#207)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: πŸ’‘ sort connection_recordings by start_time βœ… Closes: ICU-8961 * refactor: πŸ’‘ remove ember array cast for connection_recordings * refactor: πŸ’‘ let to const --- .../scopes/scope/session-recordings/session-recording.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ui/admin/app/routes/scopes/scope/session-recordings/session-recording.js b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording.js index b4d2e2f43..7945ba9d1 100644 --- a/ui/admin/app/routes/scopes/scope/session-recordings/session-recording.js +++ b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording.js @@ -33,6 +33,10 @@ export default class ScopesScopeSessionRecordingsSessionRecordingRoute extends R storage_bucket_id ); } + const sortedConnections = sessionRecording.connection_recordings + .sortBy('start_time') + .reverse(); + sessionRecording.connection_recordings = sortedConnections; return { sessionRecording, From 26d676f134b0005c03468148a36fb14eeabc61de Mon Sep 17 00:00:00 2001 From: Zhihe Li Date: Wed, 19 Apr 2023 15:51:56 -0400 Subject: [PATCH 129/193] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Fix=20deleted=20r?= =?UTF-8?q?esources=20existing=20on=20session=20recordings=20(#205)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- addons/api/mirage/factories/session-recording.js | 12 ++++++------ addons/api/mirage/models/session-recording.js | 3 --- .../tests/acceptance/session-recordings/list-test.js | 2 +- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/addons/api/mirage/factories/session-recording.js b/addons/api/mirage/factories/session-recording.js index 39abefb7d..717a4da52 100644 --- a/addons/api/mirage/factories/session-recording.js +++ b/addons/api/mirage/factories/session-recording.js @@ -36,9 +36,9 @@ export default factory.extend({ target.id = 'deleted_target'; sessionRecording.update({ - user, - target, - session, + user: user.attrs, + target: target.attrs, + sessionId: session.id, }); }, }), @@ -52,9 +52,9 @@ export default factory.extend({ ); sessionRecording.update({ - user, - target, - session, + user: user.attrs, + target: target.attrs, + sessionId: session.id, }); }, }), diff --git a/addons/api/mirage/models/session-recording.js b/addons/api/mirage/models/session-recording.js index c9ad6b47c..924431085 100644 --- a/addons/api/mirage/models/session-recording.js +++ b/addons/api/mirage/models/session-recording.js @@ -7,8 +7,5 @@ import { belongsTo, hasMany, Model } from 'miragejs'; export default Model.extend({ scope: belongsTo(), - user: belongsTo(), - session: belongsTo(), - target: belongsTo(), connection_recordings: hasMany(), }); diff --git a/ui/admin/tests/acceptance/session-recordings/list-test.js b/ui/admin/tests/acceptance/session-recordings/list-test.js index acd15f203..30faa21ed 100644 --- a/ui/admin/tests/acceptance/session-recordings/list-test.js +++ b/ui/admin/tests/acceptance/session-recordings/list-test.js @@ -38,7 +38,7 @@ module('Acceptance | session recordings | list', function (hooks) { scope: instances.scopes.global, }); instances.sessionRecording = this.server.create('session-recording', { - target: instances.scopes.targetModel, + target: instances.scopes.targetModel.attrs, }); urls.globalScope = `/scopes/global`; urls.sessionRecordings = `${urls.globalScope}/session-recordings`; From c11aa3d4f2176d54fc029091c2a5f0d4db57b897 Mon Sep 17 00:00:00 2001 From: Randall Morey Date: Wed, 19 Apr 2023 14:06:18 -0700 Subject: [PATCH 130/193] =?UTF-8?q?refactor:=20=F0=9F=92=A1=20loading=20of?= =?UTF-8?q?=20buckets=20in=20recordings=20routes=20could=20fail=20(#208)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: πŸ’‘ loading of buckets in recordings routes could fail * Update ui/admin/app/controllers/scopes/scope/session-recordings/index.js Co-authored-by: Dharini Jeeva * Update ui/admin/app/controllers/scopes/scope/session-recordings/index.js Co-authored-by: Dharini Jeeva --------- Co-authored-by: Dharini Jeeva --- .../scopes/scope/session-recordings/index.js | 4 ++-- .../routes/scopes/scope/session-recordings.js | 20 ++++++++++++++----- .../session-recordings/session-recording.js | 17 ++++++++++------ 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/ui/admin/app/controllers/scopes/scope/session-recordings/index.js b/ui/admin/app/controllers/scopes/scope/session-recordings/index.js index ee4b8092b..6d9f05688 100644 --- a/ui/admin/app/controllers/scopes/scope/session-recordings/index.js +++ b/ui/admin/app/controllers/scopes/scope/session-recordings/index.js @@ -6,7 +6,7 @@ export default class ScopesScopeSessionRecordingsIndexController extends Control * @type {boolean} */ get hasSessionRecordings() { - return this.model.sessionRecordings.length > 0; + return this.model?.sessionRecordings?.length; } /** @@ -14,6 +14,6 @@ export default class ScopesScopeSessionRecordingsIndexController extends Control * @type {boolean} */ get hasSessionRecordingsConfigured() { - return this.model.storageBuckets.length > 0; + return this.model?.storageBuckets?.length; } } diff --git a/ui/admin/app/routes/scopes/scope/session-recordings.js b/ui/admin/app/routes/scopes/scope/session-recordings.js index e18a61020..4715a8a71 100644 --- a/ui/admin/app/routes/scopes/scope/session-recordings.js +++ b/ui/admin/app/routes/scopes/scope/session-recordings.js @@ -23,18 +23,28 @@ export default class ScopesScopeSessionRecordingsRoute extends Route { * @return {{sessionRecordings: Array, storageBuckets: Array}} */ async model() { + let storageBuckets; + const scope = this.modelFor('scopes.scope'); - // if (this.can.can('list session-recording', scope, { collection: 'session-recordings' })) { const { id: scope_id } = scope; + // if (this.can.can('list session-recording', scope, { collection: 'session-recordings' })) { const sessionRecordings = await this.store.query('session-recording', { scope_id, recursive: true, }); - const storageBuckets = await this.store.query('storage-bucket', { - scope_id, - recursive: true, - }); + + // Storage buckets could fail for a number of reasons, including that + // the user isn't authorized to access them. + try { + storageBuckets = await this.store.query('storage-bucket', { + scope_id, + recursive: true, + }); + } catch (e) { + // no op + } + return { sessionRecordings, storageBuckets, diff --git a/ui/admin/app/routes/scopes/scope/session-recordings/session-recording.js b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording.js index 7945ba9d1..8e28a9802 100644 --- a/ui/admin/app/routes/scopes/scope/session-recordings/session-recording.js +++ b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording.js @@ -26,12 +26,17 @@ export default class ScopesScopeSessionRecordingsSessionRecordingRoute extends R 'session-recording', session_recording_id ); - if (sessionRecording.target?.storage_bucket_id) { - const { storage_bucket_id } = sessionRecording.target; - storageBucket = await this.store.findRecord( - 'storage-bucket', - storage_bucket_id - ); + + try { + if (sessionRecording.target?.storage_bucket_id) { + const { storage_bucket_id } = sessionRecording.target; + storageBucket = await this.store.findRecord( + 'storage-bucket', + storage_bucket_id + ); + } + } catch (e) { + // no op } const sortedConnections = sessionRecording.connection_recordings .sortBy('start_time') From f1fde7f2a4a15ec64ca839f483f0fde5a98a5611 Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Corvo Date: Thu, 20 Apr 2023 10:38:33 -0700 Subject: [PATCH 131/193] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Fix=20channel=20i?= =?UTF-8?q?nformation=20(#210)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix Channel information, before we were using session-recording (wrong) now we are using the channel-recording --- .../scope/session-recordings/session-recording/index.hbs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs index 5a8f942b7..073f994ac 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs @@ -47,17 +47,15 @@ {{! Bytes up }} - {{format-bytes-size @model.sessionRecording.bytes_up}} + {{format-bytes-size B.data.bytes_up}} {{! Bytes down }} - {{format-bytes-size @model.sessionRecording.bytes_down}} + {{format-bytes-size B.data.bytes_down}} {{! Duration }} - {{format-time-duration - @model.sessionRecording.duration - }} + {{format-time-duration B.data.duration}}
    From ebe504ff6a09cfa12918b24371b16e6baa78e5a7 Mon Sep 17 00:00:00 2001 From: Cameron Perera Date: Fri, 21 Apr 2023 12:20:25 -0500 Subject: [PATCH 132/193] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20sort=20Connectio?= =?UTF-8?q?ns=20and=20Channels=20by=20start=5Ftime=20(#213)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit βœ… Closes: ICU-8962 --- .../session-recordings/session-recording.js | 19 +++++++++++++++---- .../session-recording/index.hbs | 9 +++------ 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/ui/admin/app/routes/scopes/scope/session-recordings/session-recording.js b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording.js index 8e28a9802..fa7d5f926 100644 --- a/ui/admin/app/routes/scopes/scope/session-recordings/session-recording.js +++ b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording.js @@ -17,8 +17,9 @@ export default class ScopesScopeSessionRecordingsSessionRecordingRoute extends R } /** - * Load session recording and related storage bucket if present - * @return {SessionRecordingModel, ?StorageBucketModel} + * Load session recording, sorted connections and channels, + * and related storage bucket if present + * @return {SessionRecordingModel, [ConnectionRecordingModel] ?StorageBucketModel} */ async model({ session_recording_id }) { let storageBucket = null; @@ -38,13 +39,23 @@ export default class ScopesScopeSessionRecordingsSessionRecordingRoute extends R } catch (e) { // no op } + const sortedConnections = sessionRecording.connection_recordings .sortBy('start_time') - .reverse(); - sessionRecording.connection_recordings = sortedConnections; + .reverse() + .map((connection) => { + const sortedChannels = connection.channel_recordings + .sortBy('start_time') + .reverse(); + return { + connection, + channels: sortedChannels, + }; + }); return { sessionRecording, + sortedConnections, storageBucket, }; } diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs index 073f994ac..9c110729d 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/index.hbs @@ -11,18 +11,15 @@
    - {{#each - @model.sessionRecording.connection_recordings - as |connection| - }} + {{#each @model.sortedConnections as |connection|}}

    {{t 'resources.session-recording.connection.title'}} - {{connection.id}} + {{connection.connection.id}}

    Date: Fri, 21 Apr 2023 16:24:26 -0500 Subject: [PATCH 133/193] =?UTF-8?q?refactor:=20=F0=9F=92=A1=20Update=20ses?= =?UTF-8?q?sion=20recording=20route=20model=20signature=20(#216)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../routes/scopes/scope/session-recordings/session-recording.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/admin/app/routes/scopes/scope/session-recordings/session-recording.js b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording.js index fa7d5f926..4e3664267 100644 --- a/ui/admin/app/routes/scopes/scope/session-recordings/session-recording.js +++ b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording.js @@ -19,7 +19,7 @@ export default class ScopesScopeSessionRecordingsSessionRecordingRoute extends R /** * Load session recording, sorted connections and channels, * and related storage bucket if present - * @return {SessionRecordingModel, [ConnectionRecordingModel] ?StorageBucketModel} + * @return {{sessionRecording: SessionRecordingModel, sortedConnections: [ConnectionRecordingModel], storageBucket: ?StorageBucketModel}} */ async model({ session_recording_id }) { let storageBucket = null; From 87aea507f8f60877f74f0040f843e8924e0da91f Mon Sep 17 00:00:00 2001 From: Cameron Perera Date: Fri, 21 Apr 2023 16:39:13 -0500 Subject: [PATCH 134/193] =?UTF-8?q?refactor:=20=F0=9F=92=A1=20enable=20per?= =?UTF-8?q?mission=20for=20listing=20session=20recordings=20(#215)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit βœ… Closes: ICU-9003 --- .../routes/scopes/scope/session-recordings.js | 40 ++++++++++--------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/ui/admin/app/routes/scopes/scope/session-recordings.js b/ui/admin/app/routes/scopes/scope/session-recordings.js index 4715a8a71..8d26602ae 100644 --- a/ui/admin/app/routes/scopes/scope/session-recordings.js +++ b/ui/admin/app/routes/scopes/scope/session-recordings.js @@ -28,28 +28,32 @@ export default class ScopesScopeSessionRecordingsRoute extends Route { const scope = this.modelFor('scopes.scope'); const { id: scope_id } = scope; - // if (this.can.can('list session-recording', scope, { collection: 'session-recordings' })) { - const sessionRecordings = await this.store.query('session-recording', { - scope_id, - recursive: true, - }); - - // Storage buckets could fail for a number of reasons, including that - // the user isn't authorized to access them. - try { - storageBuckets = await this.store.query('storage-bucket', { + if ( + this.can.can('list session-recording', scope, { + collection: 'session-recordings', + }) + ) { + const sessionRecordings = await this.store.query('session-recording', { scope_id, recursive: true, }); - } catch (e) { - // no op - } - return { - sessionRecordings, - storageBuckets, - }; - // } + // Storage buckets could fail for a number of reasons, including that + // the user isn't authorized to access them. + try { + storageBuckets = await this.store.query('storage-bucket', { + scope_id, + recursive: true, + }); + } catch (e) { + // no op + } + + return { + sessionRecordings, + storageBuckets, + }; + } } // =actions From db408a9acd01e743be281700706a6e18397a14fb Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Corvo Date: Mon, 24 Apr 2023 08:17:27 -0700 Subject: [PATCH 135/193] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20Add=20related=20?= =?UTF-8?q?info=20to=20session=20recording=20and=20player=20(#195)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 🎸 Add related info to session recording and player --------- Co-authored-by: Cameron Perera --- .../components/link-list-panel/item/index.hbs | 39 ++++++--- .../channels-by-connection/channel.hbs | 60 ++++++++++---- .../session-recording/index.hbs | 61 ++++++++++---- .../components/link-list-panel/index-test.js | 82 +++++++++++++++++++ 4 files changed, 199 insertions(+), 43 deletions(-) diff --git a/ui/admin/app/components/link-list-panel/item/index.hbs b/ui/admin/app/components/link-list-panel/item/index.hbs index a7d185b5f..38456f6d6 100644 --- a/ui/admin/app/components/link-list-panel/item/index.hbs +++ b/ui/admin/app/components/link-list-panel/item/index.hbs @@ -1,19 +1,36 @@ \ No newline at end of file diff --git a/ui/admin/app/components/session-recording/status/index.hbs b/ui/admin/app/components/session-recording/status/index.hbs index 555142b31..9ad3f53cb 100644 --- a/ui/admin/app/components/session-recording/status/index.hbs +++ b/ui/admin/app/components/session-recording/status/index.hbs @@ -1,4 +1,5 @@ {{! Status }} - + {{! User }} diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/index.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/index.hbs index 0bfb54bb7..e0d306e58 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/index.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/index.hbs @@ -114,6 +114,12 @@

    {{t 'resources.session-recording.details'}}

    + {{! Session Recording Status }} + + + {{! Start time }} {{#if @model.sessionRecording.start_time}} diff --git a/ui/admin/tests/integration/components/metadata-list/index-test.js b/ui/admin/tests/integration/components/metadata-list/index-test.js index 91cb1d7c2..90b08a598 100644 --- a/ui/admin/tests/integration/components/metadata-list/index-test.js +++ b/ui/admin/tests/integration/components/metadata-list/index-test.js @@ -42,4 +42,20 @@ module('Integration | Component | metadata-list/item', function (hooks) { assert.dom('li.metadata-list-item').hasClass('hds-foreground-action'); assert.dom('li.metadata-list-item').hasText('Sample text 2'); }); + + test('it renders no icon if @icon not provided', async function (assert) { + assert.expect(2); + await render(hbs` + + + Sample text 3 + + + `); + + assert.dom('.flight-icon').isNotVisible(); + assert.dom('li.metadata-list-item').hasText('Sample text 3'); + }); }); From c63c95fd511876c497d0d8d6610fd32bd9b85b1d Mon Sep 17 00:00:00 2001 From: Zhihe Li Date: Wed, 24 May 2023 17:57:30 -0400 Subject: [PATCH 174/193] =?UTF-8?q?chore:=20=F0=9F=A4=96=20Update=20serial?= =?UTF-8?q?izer=20for=20storage=20buckets=20(#282)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/addon/serializers/storage-bucket.js | 15 ++++-- .../unit/serializers/storage-bucket-test.js | 49 +++++++++++++++++++ .../acceptance/storage-buckets/update-test.js | 6 +-- 3 files changed, 63 insertions(+), 7 deletions(-) diff --git a/addons/api/addon/serializers/storage-bucket.js b/addons/api/addon/serializers/storage-bucket.js index ae8e818d5..e4f928253 100644 --- a/addons/api/addon/serializers/storage-bucket.js +++ b/addons/api/addon/serializers/storage-bucket.js @@ -1,13 +1,22 @@ import ApplicationSerializer from './application'; export default class StorageBucketSerializer extends ApplicationSerializer { + serialize(snapshot) { + const serialized = super.serialize(...arguments); + if (!snapshot.record.isNew) { + delete serialized.bucket_name; + delete serialized.bucket_prefix; + } + return serialized; + } + normalize(typeClass, hash, ...rest) { const normalizedHash = structuredClone(hash); const normalized = super.normalize(typeClass, normalizedHash, ...rest); - // Remove secret fields - delete normalized.data.attributes.access_key_id; - delete normalized.data.attributes.secret_access_key; + // Remove secret fields so we don't track them after creating/updating + normalized.data.attributes.access_key_id = null; + normalized.data.attributes.secret_access_key = null; return normalized; } } diff --git a/addons/api/tests/unit/serializers/storage-bucket-test.js b/addons/api/tests/unit/serializers/storage-bucket-test.js index b2a6aeac0..5cb1406e4 100644 --- a/addons/api/tests/unit/serializers/storage-bucket-test.js +++ b/addons/api/tests/unit/serializers/storage-bucket-test.js @@ -52,6 +52,53 @@ module('Unit | Serializer | storage bucket', function (hooks) { assert.deepEqual(record.serialize(), expectedResult); }); + test('it serializes when updating correctly', async function (assert) { + assert.expect(1); + const store = this.owner.lookup('service:store'); + const serializer = store.serializerFor('storage-bucket'); + store.push({ + data: { + id: '1', + type: 'storage-bucket', + attributes: { + type: TYPE_STORAGE_BUCKET_PLUGIN, + compositeType: TYPE_STORAGE_BUCKET_PLUGIN_AWS_S3, + name: 'AWS', + description: 'this has an aws plugin', + bucket_name: 'bucketname', + bucket_prefix: 'bucketprefix', + worker_filter: 'workerfilter', + region: 'eu-west-1', + access_key_id: 'foobars', + secret_access_key: 'testing', + secrets_hmac: 'hmac', + disable_credential_rotation: true, + version: 1, + }, + }, + }); + const record = store.peekRecord('storage-bucket', '1'); + const snapshot = record._createSnapshot(); + const serializedRecord = serializer.serialize(snapshot); + + const expectedResult = { + name: 'AWS', + description: 'this has an aws plugin', + type: TYPE_STORAGE_BUCKET_PLUGIN, + worker_filter: 'workerfilter', + attributes: { + region: 'eu-west-1', + disable_credential_rotation: true, + }, + secrets: { + access_key_id: 'foobars', + secret_access_key: 'testing', + }, + version: 1, + }; + assert.deepEqual(serializedRecord, expectedResult); + }); + test('it normalizes correctly', function (assert) { assert.expect(1); const store = this.owner.lookup('service:store'); @@ -94,6 +141,8 @@ module('Unit | Serializer | storage bucket', function (hooks) { secrets_hmac: 'this is secret', region: 'eu-west-1', disable_credential_rotation: true, + access_key_id: null, + secret_access_key: null, }, type: 'storage-bucket', relationships: {}, diff --git a/ui/admin/tests/acceptance/storage-buckets/update-test.js b/ui/admin/tests/acceptance/storage-buckets/update-test.js index 959df68e3..b8aced512 100644 --- a/ui/admin/tests/acceptance/storage-buckets/update-test.js +++ b/ui/admin/tests/acceptance/storage-buckets/update-test.js @@ -111,10 +111,8 @@ module('Acceptance | storage-buckets | update', function (hooks) { await click(SAVE_BUTTON_SELECTOR, 'Click save'); assert.dom(SECRET_FIELD_BUTTON_SELECTOR).isDisabled(); - assert.dom(ACCESS_KEY_ID_FIELD_SELECTOR).hasValue(ACCESS_KEY_ID_FIELD_TEXT); - assert - .dom(SECRET_ACCESS_KEY_FIELD_SELECTOR) - .hasValue(SECRET_ACCESS_KEY_FIELD_TEXT); + assert.dom(ACCESS_KEY_ID_FIELD_SELECTOR).hasNoValue(); + assert.dom(SECRET_ACCESS_KEY_FIELD_SELECTOR).hasNoValue(); }); test('can cancel changes to access key fields', async function (assert) { From bf13b718072153dcfb8d8a64ae170dff8d449d36 Mon Sep 17 00:00:00 2001 From: Dharini Jeeva Date: Wed, 24 May 2023 16:02:39 -0700 Subject: [PATCH 175/193] =?UTF-8?q?refactor:=20=F0=9F=92=A1=20title=20case?= =?UTF-8?q?,=20remove=20ID=20(#286)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- addons/core/translations/resources/en-us.yaml | 2 +- .../scope/targets/target/enable-session-recording.hbs | 8 -------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml index 03845d899..21c1f7b28 100644 --- a/addons/core/translations/resources/en-us.yaml +++ b/addons/core/translations/resources/en-us.yaml @@ -452,7 +452,7 @@ target: title: Enable Session Recording messages: add: - title: Enable session recording for target + title: Enable Session Recording for Target form: filter: label: Record sessions for this target diff --git a/ui/admin/app/templates/scopes/scope/targets/target/enable-session-recording.hbs b/ui/admin/app/templates/scopes/scope/targets/target/enable-session-recording.hbs index 89818dfa6..2bad153c7 100644 --- a/ui/admin/app/templates/scopes/scope/targets/target/enable-session-recording.hbs +++ b/ui/admin/app/templates/scopes/scope/targets/target/enable-session-recording.hbs @@ -9,14 +9,6 @@

    {{t 'resources.target.enable-session-recording.messages.add.title'}}

    - - - {{@model.target.id}} - From 33afb64476b3ec608b3668a370aabae81ad710a8 Mon Sep 17 00:00:00 2001 From: Cameron Perera Date: Thu, 25 May 2023 10:31:51 -0500 Subject: [PATCH 176/193] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20add=20no=20chann?= =?UTF-8?q?els=20message=20for=20empty=20connections=20(#287)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit βœ… Closes: ICU-9443 --- addons/core/translations/resources/en-us.yaml | 2 + ui/admin/app/styles/app.scss | 4 + .../channels-by-connection/index.hbs | 154 ++++++++++-------- 3 files changed, 89 insertions(+), 71 deletions(-) diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml index 21c1f7b28..d843a0f32 100644 --- a/addons/core/translations/resources/en-us.yaml +++ b/addons/core/translations/resources/en-us.yaml @@ -232,6 +232,8 @@ session-recording: label: Summary channels-by-connection: title: Channels by connection + messages: + no-channels: There are no channels for this connection channel: title: Channel title_index: Channel {index} diff --git a/ui/admin/app/styles/app.scss b/ui/admin/app/styles/app.scss index dc35c0260..5153981b7 100644 --- a/ui/admin/app/styles/app.scss +++ b/ui/admin/app/styles/app.scss @@ -934,6 +934,10 @@ &-connection-header { padding: 0.875rem 1rem; } + + .no-channels-message { + padding: 0 1rem; + } } // Channel diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/index.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/index.hbs index e0d306e58..440113cc4 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/index.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/index.hbs @@ -31,82 +31,94 @@ {{connection.id}}
    - - <:body as |B|> - - - - {{indexed-display-name - 'resources.session-recording.channel.title_index' - connection.channel_recordings - B.data - }} - - - - - {{! Bytes up }} - - {{t - 'resources.session-recording.up' - bytes=(format-bytes-size B.data.bytes_up) + (hash label=(t 'form.id.label')) + (hash label='' align='right') + }} + > + <:body as |B|> + + + + {{indexed-display-name + 'resources.session-recording.channel.title_index' + connection.channel_recordings + B.data }} - - {{! Bytes down }} - - {{t - 'resources.session-recording.down' - bytes=(format-bytes-size B.data.bytes_down) - }} - - {{! Duration }} - {{#if B.data.duration}} - - {{format-time-duration B.data.duration}} + + + + + {{! Bytes up }} + + {{t + 'resources.session-recording.up' + bytes=(format-bytes-size B.data.bytes_up) + }} + {{! Bytes down }} + + {{t + 'resources.session-recording.down' + bytes=(format-bytes-size B.data.bytes_down) + }} + + {{! Duration }} + {{#if B.data.duration}} + + {{format-time-duration B.data.duration}} + + {{/if}} + + + + + {{B.data.id}} + + + + {{#if @model.sessionRecording.isAvailable}} + {{/if}} - - - - - {{B.data.id}} - - - - {{#if @model.sessionRecording.isAvailable}} - - {{/if}} - - - - + + + + + {{else}} +
    + + + {{t + 'resources.session-recording.channels-by-connection.messages.no-channels' + }} + + +
    + {{/if}} {{/each}} From 502eba304d1fdef62445268fda58999778551ad9 Mon Sep 17 00:00:00 2001 From: Cameron Perera Date: Thu, 25 May 2023 14:58:06 -0500 Subject: [PATCH 177/193] =?UTF-8?q?refactor:=20=F0=9F=92=A1=20hide=20metad?= =?UTF-8?q?ata=20items=20if=20undefined=20(#288)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: πŸ’‘ hide metadata items if undefined * refactor: πŸ’‘ hide channel metadata if undefined --- .../channels-by-connection/channel.hbs | 28 ++++---- .../channels-by-connection/index.hbs | 68 +++++++++++-------- 2 files changed, 55 insertions(+), 41 deletions(-) diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs index 6ba0b0ea1..3786d0d3a 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs @@ -95,19 +95,23 @@ {{/if}} {{! Bytes up }} - - {{t - 'resources.session-recording.up' - bytes=(format-bytes-size @model.channelRecording.bytes_up) - }} - + {{#if @model.channelRecording.bytes_up}} + + {{t + 'resources.session-recording.up' + bytes=(format-bytes-size @model.channelRecording.bytes_up) + }} + + {{/if}} {{! Bytes down }} - - {{t - 'resources.session-recording.down' - bytes=(format-bytes-size @model.channelRecording.bytes_down) - }} - + {{#if @model.channelRecording.bytes_down}} + + {{t + 'resources.session-recording.down' + bytes=(format-bytes-size @model.channelRecording.bytes_down) + }} + + {{/if}}
    diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/index.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/index.hbs index 440113cc4..f71adf356 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/index.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/index.hbs @@ -64,19 +64,23 @@ {{! Bytes up }} - - {{t - 'resources.session-recording.up' - bytes=(format-bytes-size B.data.bytes_up) - }} - + {{#if B.data.bytes_up}} + + {{t + 'resources.session-recording.up' + bytes=(format-bytes-size B.data.bytes_up) + }} + + {{/if}} {{! Bytes down }} - - {{t - 'resources.session-recording.down' - bytes=(format-bytes-size B.data.bytes_down) - }} - + {{#if B.data.bytes_down}} + + {{t + 'resources.session-recording.down' + bytes=(format-bytes-size B.data.bytes_down) + }} + + {{/if}} {{! Duration }} {{#if B.data.duration}} @@ -127,11 +131,13 @@ {{! Session Recording Status }} - - - + {{#if @model.sessionRecording.state}} + + + + {{/if}} {{! Start time }} {{#if @model.sessionRecording.start_time}} @@ -155,19 +161,23 @@ {{/if}} {{! Bytes up }} - - {{t - 'resources.session-recording.up' - bytes=(format-bytes-size @model.sessionRecording.bytes_up) - }} - + {{#if @model.sessionRecording.bytes_up}} + + {{t + 'resources.session-recording.up' + bytes=(format-bytes-size @model.sessionRecording.bytes_up) + }} + + {{/if}} {{! Bytes down }} - - {{t - 'resources.session-recording.down' - bytes=(format-bytes-size @model.sessionRecording.bytes_down) - }} - + {{#if @model.sessionRecording.bytes_down}} + + {{t + 'resources.session-recording.down' + bytes=(format-bytes-size @model.sessionRecording.bytes_down) + }} + + {{/if}}
    From abeee7dc1b57aa34c2834f2890c3734b7231535a Mon Sep 17 00:00:00 2001 From: lisbet-alvarez <107949262+lisbet-alvarez@users.noreply.github.com> Date: Thu, 25 May 2023 14:43:20 -0700 Subject: [PATCH 178/193] =?UTF-8?q?refactor:=20=F0=9F=92=A1=20disable=20un?= =?UTF-8?q?editable=20storage=20bucket=20form=20fields=20(#279)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: πŸ’‘ disable uneditable storage bucket form fields βœ… Closes: ICU-9430 * refactor: πŸ’‘ update fields to be readOnly in edit mode & tests * refactor: πŸ’‘ remove duplicate field --- .../components/form/storage-bucket/index.hbs | 6 ++++-- .../acceptance/storage-buckets/create-test.js | 18 ++++++++++++++++-- .../acceptance/storage-buckets/update-test.js | 19 +++++++++++++++++++ 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/ui/admin/app/components/form/storage-bucket/index.hbs b/ui/admin/app/components/form/storage-bucket/index.hbs index 447c93edc..4df4c75dd 100644 --- a/ui/admin/app/components/form/storage-bucket/index.hbs +++ b/ui/admin/app/components/form/storage-bucket/index.hbs @@ -50,7 +50,7 @@ {{/if}} - {{#if (or @model.isNew form.isEditable)}} + {{#if @model.isNew}} - {{else if @model.scope}} + {{else}} @@ -130,6 +131,7 @@ @type='text' name='bucket_prefix' disabled={{form.disabled}} + readOnly={{not @model.isNew}} {{on 'input' (set-from-event @model 'bucket_prefix')}} as |F| > diff --git a/ui/admin/tests/acceptance/storage-buckets/create-test.js b/ui/admin/tests/acceptance/storage-buckets/create-test.js index 2457dd6ad..beb1522c2 100644 --- a/ui/admin/tests/acceptance/storage-buckets/create-test.js +++ b/ui/admin/tests/acceptance/storage-buckets/create-test.js @@ -19,6 +19,8 @@ module('Acceptance | storage-buckets | create', function (hooks) { const ALERT_TEXT_SELECTOR = '[role="alert"] div'; const FIELD_ERROR_TEXT_SELECTOR = '.hds-form-error__message'; const NAME_FIELD_TEXT = 'random string'; + const BUCKET_NAME_FIELD_SELECTOR = '[name="bucket_name"]'; + const BUCKET_PREFIX_FIELD_SELECTOR = '[name="bucket_prefix"]'; const instances = { scopes: { @@ -51,13 +53,19 @@ module('Acceptance | storage-buckets | create', function (hooks) { }); test('users can create a new storage bucket with global scope', async function (assert) { - assert.expect(3); + assert.expect(7); const storageBucketCount = getStorageBucketCount(); await visit(urls.storageBuckets); await click(`[href="${urls.newStorageBucket}"]`); await fillIn(NAME_FIELD_SELECTOR, NAME_FIELD_TEXT); await click('[value="global"]'); + + assert.dom(BUCKET_NAME_FIELD_SELECTOR).isNotDisabled(); + assert.dom(BUCKET_PREFIX_FIELD_SELECTOR).isNotDisabled(); + assert.dom(BUCKET_NAME_FIELD_SELECTOR).doesNotHaveAttribute('readOnly'); + assert.dom(BUCKET_PREFIX_FIELD_SELECTOR).doesNotHaveAttribute('readOnly'); + await click(SAVE_BTN_SELECTOR); const storageBucket = this.server.schema.storageBuckets.findBy({ name: NAME_FIELD_TEXT, @@ -69,13 +77,19 @@ module('Acceptance | storage-buckets | create', function (hooks) { }); test('users can create a new storage bucket with org scope', async function (assert) { - assert.expect(3); + assert.expect(7); const storageBucketCount = getStorageBucketCount(); await visit(urls.storageBuckets); await click(`[href="${urls.newStorageBucket}"]`); await fillIn(NAME_FIELD_SELECTOR, NAME_FIELD_TEXT); await click(`[value="${instances.scopes.org.scope.id}"]`); + + assert.dom(BUCKET_NAME_FIELD_SELECTOR).isNotDisabled(); + assert.dom(BUCKET_PREFIX_FIELD_SELECTOR).isNotDisabled(); + assert.dom(BUCKET_NAME_FIELD_SELECTOR).doesNotHaveAttribute('readOnly'); + assert.dom(BUCKET_PREFIX_FIELD_SELECTOR).doesNotHaveAttribute('readOnly'); + await click(SAVE_BTN_SELECTOR); const storageBucket = this.server.schema.storageBuckets.findBy({ name: NAME_FIELD_TEXT, diff --git a/ui/admin/tests/acceptance/storage-buckets/update-test.js b/ui/admin/tests/acceptance/storage-buckets/update-test.js index b8aced512..aec19b55e 100644 --- a/ui/admin/tests/acceptance/storage-buckets/update-test.js +++ b/ui/admin/tests/acceptance/storage-buckets/update-test.js @@ -28,6 +28,8 @@ module('Acceptance | storage-buckets | update', function (hooks) { const NAME_FIELD_TEXT = 'Updated storage-bucket name'; const ACCESS_KEY_ID_FIELD_TEXT = 'Updated access key id'; const SECRET_ACCESS_KEY_FIELD_TEXT = 'Update secret access key'; + const BUCKET_NAME_FIELD_SELECTOR = '[name="bucket_name"]'; + const BUCKET_PREFIX_FIELD_SELECTOR = '[name="bucket_prefix"]'; const instances = { scopes: { @@ -171,4 +173,21 @@ module('Acceptance | storage-buckets | update', function (hooks) { assert.dom(ALERT_TEXT_SELECTOR).hasText('The request was invalid.'); assert.dom(FIELD_ERROR_TEXT_SELECTOR).hasText('Region is required.'); }); + + test('user cannot edit bucket name and bucket prefix fields in a storage bucket form', async function (assert) { + assert.expect(6); + await visit(urls.storageBuckets); + + await click(`[href="${urls.storageBucket}"]`); + + assert.dom(BUCKET_NAME_FIELD_SELECTOR).isDisabled(); + assert.dom(BUCKET_PREFIX_FIELD_SELECTOR).isDisabled(); + + await click(BUTTON_SELECTOR, 'Click edit mode'); + + assert.dom(BUCKET_NAME_FIELD_SELECTOR).hasAttribute('readOnly'); + assert.dom(BUCKET_PREFIX_FIELD_SELECTOR).hasAttribute('readOnly'); + assert.dom(BUCKET_NAME_FIELD_SELECTOR).isNotDisabled(); + assert.dom(BUCKET_PREFIX_FIELD_SELECTOR).isNotDisabled(); + }); }); From 0d161a5623855d3986070260c25686bac988fb56 Mon Sep 17 00:00:00 2001 From: Dharini Jeeva Date: Thu, 25 May 2023 15:54:32 -0700 Subject: [PATCH 179/193] =?UTF-8?q?fix:=20=F0=9F=90=9B=20form=20abandon=20?= =?UTF-8?q?confirmation=20popup=20in=20enable=20session=20recording=20rout?= =?UTF-8?q?e=20(#289)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: πŸ› form abandon confirmation popup --- .../target/enable-session-recording/index.hbs | 6 +--- .../target/enable-session-recording.js | 33 ++++++++++++------- .../target/enable-session-recording.hbs | 8 ++--- 3 files changed, 26 insertions(+), 21 deletions(-) diff --git a/ui/admin/app/components/form/target/enable-session-recording/index.hbs b/ui/admin/app/components/form/target/enable-session-recording/index.hbs index 1ea694806..3c18649f0 100644 --- a/ui/admin/app/components/form/target/enable-session-recording/index.hbs +++ b/ui/admin/app/components/form/target/enable-session-recording/index.hbs @@ -1,8 +1,4 @@ - +
    From 9d7905402e7a6f10abefcc9d89654cc7022f058a Mon Sep 17 00:00:00 2001 From: Cameron Perera Date: Fri, 26 May 2023 12:27:27 -0500 Subject: [PATCH 180/193] Fix player fullscreen issue (#292) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: πŸ’‘ layout grid columns * fix: πŸ› fix issue where player stays at fullscreen size on exit βœ… Closes: ICU-9456 --- ui/admin/app/styles/app.scss | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ui/admin/app/styles/app.scss b/ui/admin/app/styles/app.scss index 5153981b7..673f69842 100644 --- a/ui/admin/app/styles/app.scss +++ b/ui/admin/app/styles/app.scss @@ -880,7 +880,7 @@ .layout-sidebar { display: grid; grid-template-areas: 'body body sidebar'; - grid-template-columns: auto auto 300px; + grid-template-columns: 1fr 1fr 300px; grid-template-rows: auto 1fr; gap: 2rem; @@ -904,6 +904,10 @@ 'sidebar'; grid-template-columns: auto; + .layout-sidebar-body { + min-width: 0; + } + .layout-sidebar-sidebar { max-width: 300px; } From 0aef13446bfe5de2fa5746a4b0d625506b9aa0fe Mon Sep 17 00:00:00 2001 From: Cameron Perera Date: Fri, 26 May 2023 13:05:34 -0500 Subject: [PATCH 181/193] Update ember player (#290) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: πŸ€– update ember-asciinema-player * refactor: πŸ’‘ update player styles after player update * test: πŸ’ update class selector for player test * refactor: πŸ’‘ remove custom border-width from player styles --- ui/admin/app/styles/app.scss | 27 +++++++++---------- ui/admin/package.json | 2 +- .../session-recording/player-test.js | 2 +- yarn.lock | 14 +++++----- 4 files changed, 22 insertions(+), 23 deletions(-) diff --git a/ui/admin/app/styles/app.scss b/ui/admin/app/styles/app.scss index 673f69842..63db717cf 100644 --- a/ui/admin/app/styles/app.scss +++ b/ui/admin/app/styles/app.scss @@ -805,46 +805,45 @@ background-color: var(--player-background-color); } - .asciinema-terminal { + pre.ap-terminal { background-color: var(--player-background-color); border-color: var(--player-background-color); - border-width: 1rem; } - .asciinema-player { + .ap-player { border-radius: 0.75rem; // hides large play icon overlay - .start-prompt { + .ap-overlay { display: none; } } - .asciinema-player-wrapper { - &.hud .control-bar { + .ap-wrapper { + &.ap-hud .ap-control-bar { bottom: 0; } - .control-bar { + .ap-control-bar { bottom: -3.625rem; background: var(--player-background-color); border-top: var(--player-divider) 0.125rem solid; height: 3.625rem; - .playback-button { + .ap-playback-button { background: var(--player-play-button); border: var(--player-play-button-border) 0.063rem solid; border-radius: 0.313rem; margin: 0.75rem; padding: 0.625rem 1rem; - .icon path { + .ap-icon path { fill: var(--player-white); } } } - .timer { + .ap-timer { font-family: var(--token-typography-body-base-font-family); font-size: var(--token-typography-body-base-font-size); line-height: var(--token-typography-body-base-line-height); @@ -853,10 +852,10 @@ top: 40%; } - .progressbar { + .ap-progressbar { padding-top: 0.875rem; - .bar .gutter { + .ap-bar .ap-gutter { background-color: var(--player-control-bar-buffer); span { @@ -865,10 +864,10 @@ } } - .fullscreen-button { + .ap-fullscreen-button { padding-top: 1.5rem; - .icon path { + .ap-icon path { fill: var(--player-white); } } diff --git a/ui/admin/package.json b/ui/admin/package.json index 37f0d47ff..5700ea196 100644 --- a/ui/admin/package.json +++ b/ui/admin/package.json @@ -52,7 +52,7 @@ "@faker-js/faker": "^7.3.0", "@glimmer/component": "^1.1.2", "@glimmer/tracking": "^1.1.2", - "@hashicorp/ember-asciinema-player": "https://github.com/hashicorp/ember-asciinema-player.git#144eeec053fc5ccf1f0afc244b0afed4b72835b4", + "@hashicorp/ember-asciinema-player": "https://github.com/hashicorp/ember-asciinema-player.git#e047a096039cff70234c232efe75dcad74c6358a", "@playwright/test": "^1.30.0", "babel-loader": "^8.2.5", "broccoli-asset-rev": "^3.0.0", diff --git a/ui/admin/tests/integration/components/session-recording/player-test.js b/ui/admin/tests/integration/components/session-recording/player-test.js index 9f092b1b3..d299706a7 100644 --- a/ui/admin/tests/integration/components/session-recording/player-test.js +++ b/ui/admin/tests/integration/components/session-recording/player-test.js @@ -32,6 +32,6 @@ module('Integration | Component | session-recording/player', function (hooks) { `); assert.dom('.session-recording-player-header').hasText('Back to channels'); - assert.dom('.control-bar .timer').hasText('--:----:--'); + assert.dom('.ap-control-bar .ap-timer').hasText('--:----:--'); }); }); diff --git a/yarn.lock b/yarn.lock index 6d1fd8f20..e4050a99e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4713,11 +4713,11 @@ resolved "https://registry.yarnpkg.com/@hashicorp/design-system-tokens/-/design-system-tokens-1.4.1.tgz#461ee2ff7ccc46eb83098c30c20c6bba33e49cd0" integrity sha512-e5bolI2Ch1+AW2/tQrkHG6QPx4g1oONum36CfhBmX4gDChpAVoBbTG2BT+XnlBJOM5vk1uuL39ysM5QSn/BZYQ== -"@hashicorp/ember-asciinema-player@https://github.com/hashicorp/ember-asciinema-player.git#144eeec053fc5ccf1f0afc244b0afed4b72835b4": +"@hashicorp/ember-asciinema-player@https://github.com/hashicorp/ember-asciinema-player.git#e047a096039cff70234c232efe75dcad74c6358a": version "0.0.0" - resolved "https://github.com/hashicorp/ember-asciinema-player.git#144eeec053fc5ccf1f0afc244b0afed4b72835b4" + resolved "https://github.com/hashicorp/ember-asciinema-player.git#e047a096039cff70234c232efe75dcad74c6358a" dependencies: - asciinema-player "^3.0.1" + asciinema-player "^3.4.0" ember-auto-import "^2.5.0" ember-cli-babel "^7.26.11" ember-cli-htmlbars "^6.1.1" @@ -8516,10 +8516,10 @@ asar@^3.1.0: optionalDependencies: "@types/glob" "^7.1.1" -asciinema-player@^3.0.1: - version "3.3.0" - resolved "https://registry.yarnpkg.com/asciinema-player/-/asciinema-player-3.3.0.tgz#45616fa8dc3950c2be12b51d0a365ea2b9a845c2" - integrity sha512-4uyCGe83+5gZ06jgIGyV4vl0TS3egBgW0NXyCpDuDDvmzDGHEG8OICChrTecmTvajgLyq8YQet9nI7SYkVt8vQ== +asciinema-player@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/asciinema-player/-/asciinema-player-3.4.0.tgz#8664e0b305ac03acd94d0ab1ff0be0e8ca4dcff8" + integrity sha512-dX6jt5S3K6daItsVWzyY9mRDK+ivC2QgqCxFkdSiNslo0vY/ZqA4upcTzqIKZqBtxppovOZk44ltg9VnHG9QVg== dependencies: "@babel/runtime" "^7.21.0" solid-js "^1.3.0" From 3d9836a55b0b8d3219ef710742737a49f8566ab4 Mon Sep 17 00:00:00 2001 From: Cameron Perera Date: Tue, 30 May 2023 11:34:07 -0500 Subject: [PATCH 182/193] Icu 9482 add no connection message for session recording with no connections (#294) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: πŸ’‘ add controller for channels-by-connection/index * feat: 🎸 show message for new session that have no connections βœ… Closes: ICU-9482 * feat: 🎸 add message for failed session with no connections (#296) βœ… Closes: ICU-9489 * refactor: πŸ’‘ remove '-' from 'in progress' usage --- addons/core/translations/resources/en-us.yaml | 6 + .../channels-by-connection/index.js | 31 +++ .../channels-by-connection/index.hbs | 250 ++++++++++-------- .../session-recording/status-test.js | 2 +- .../channels-by-connection/index-test.js | 104 ++++++++ 5 files changed, 282 insertions(+), 111 deletions(-) create mode 100644 ui/admin/app/controllers/scopes/scope/session-recordings/session-recording/channels-by-connection/index.js create mode 100644 ui/admin/tests/unit/controllers/scopes/scope/session-recordings/session-recording/channels-by-connection/index-test.js diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml index d843a0f32..3833ad15a 100644 --- a/addons/core/translations/resources/en-us.yaml +++ b/addons/core/translations/resources/en-us.yaml @@ -234,6 +234,12 @@ session-recording: title: Channels by connection messages: no-channels: There are no channels for this connection + started-no-connections: + title: Session Recording In Progress + description: The Session has started but no connections have been made. + unknown-no-connections: + title: Session Recording Failure + description: This Session cannot be played back because no connections were established, and the Session has failed. channel: title: Channel title_index: Channel {index} diff --git a/ui/admin/app/controllers/scopes/scope/session-recordings/session-recording/channels-by-connection/index.js b/ui/admin/app/controllers/scopes/scope/session-recordings/session-recording/channels-by-connection/index.js new file mode 100644 index 000000000..8a779769b --- /dev/null +++ b/ui/admin/app/controllers/scopes/scope/session-recordings/session-recording/channels-by-connection/index.js @@ -0,0 +1,31 @@ +import Controller from '@ember/controller'; +import { + STATE_SESSION_RECORDING_STARTED, + STATE_SESSION_RECORDING_UNKNOWN, +} from 'api/models/session-recording'; + +export default class ScopesScopeSessionRecordingsSessionRecordingChannelsByConnectionIndexController extends Controller { + /** + * Returns true if the session recording has started + * but has not started any connections + * @type {boolean} + */ + get isSessionInprogressWithNoConnections() { + return ( + this.model?.sessionRecording?.connection_recordings?.length === 0 && + this.model?.sessionRecording?.state === STATE_SESSION_RECORDING_STARTED + ); + } + + /** + * Returns true if the session recording state is unknown + * and has no connections + * @type {boolean} + */ + get isSessionUnknownWithNoConnections() { + return ( + this.model?.sessionRecording?.connection_recordings?.length === 0 && + this.model?.sessionRecording?.state === STATE_SESSION_RECORDING_UNKNOWN + ); + } +} diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/index.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/index.hbs index f71adf356..6ec4cfc0d 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/index.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/index.hbs @@ -11,119 +11,149 @@
    - {{#each - @model.sessionRecording.connection_recordings - as |connection| - }} -
    -

    - {{indexed-display-name - 'resources.session-recording.connection.title_index' - @model.sessionRecording.connection_recordings - connection + {{#if this.isSessionInprogressWithNoConnections}} + + {{! Session recording in progress with no connections }} + - - {{connection.id}} - -

    - {{#if connection.channel_recordings}} - + - <:body as |B|> - - - - {{indexed-display-name - 'resources.session-recording.channel.title_index' - connection.channel_recordings - B.data - }} - - - - - {{! Bytes up }} - {{#if B.data.bytes_up}} - - {{t - 'resources.session-recording.up' - bytes=(format-bytes-size B.data.bytes_up) - }} - - {{/if}} - {{! Bytes down }} - {{#if B.data.bytes_down}} - - {{t - 'resources.session-recording.down' - bytes=(format-bytes-size B.data.bytes_down) - }} - - {{/if}} - {{! Duration }} - {{#if B.data.duration}} - - {{format-time-duration B.data.duration}} - - {{/if}} - - - - - {{B.data.id}} - - - - {{#if @model.sessionRecording.isAvailable}} - - {{/if}} - - - - - {{else}} -
    - - - {{t - 'resources.session-recording.channels-by-connection.messages.no-channels' - }} - - + /> + + {{else if this.isSessionUnknownWithNoConnections}} + + {{! Session recording unknown with no connections }} + + + + {{else}} + {{#each + @model.sessionRecording.connection_recordings + as |connection| + }} +
    +

    + {{indexed-display-name + 'resources.session-recording.connection.title_index' + @model.sessionRecording.connection_recordings + connection + }} +

    + + {{connection.id}} +
    - {{/if}} - {{/each}} + {{#if connection.channel_recordings}} + + <:body as |B|> + + + + {{indexed-display-name + 'resources.session-recording.channel.title_index' + connection.channel_recordings + B.data + }} + + + + + {{! Bytes up }} + {{#if B.data.bytes_up}} + + {{t + 'resources.session-recording.up' + bytes=(format-bytes-size B.data.bytes_up) + }} + + {{/if}} + {{! Bytes down }} + {{#if B.data.bytes_down}} + + {{t + 'resources.session-recording.down' + bytes=(format-bytes-size B.data.bytes_down) + }} + + {{/if}} + {{! Duration }} + {{#if B.data.duration}} + + {{format-time-duration B.data.duration}} + + {{/if}} + + + + + {{B.data.id}} + + + + {{#if @model.sessionRecording.isAvailable}} + + {{/if}} + + + + + {{else}} +
    + + + {{t + 'resources.session-recording.channels-by-connection.messages.no-channels' + }} + + +
    + {{/if}} + {{/each}} + {{/if}}
    diff --git a/ui/admin/tests/integration/components/session-recording/status-test.js b/ui/admin/tests/integration/components/session-recording/status-test.js index 234e816c9..01c77093a 100644 --- a/ui/admin/tests/integration/components/session-recording/status-test.js +++ b/ui/admin/tests/integration/components/session-recording/status-test.js @@ -30,7 +30,7 @@ module('Integration | Component | session-recording/status', function (hooks) { assert.dom(BADGE_TEXT_SELECTOR).hasText('Completed'); }); - test('it renders an in-progress status badge', async function (assert) { + test('it renders an in progress status badge', async function (assert) { assert.expect(2); this.status = STATE_SESSION_RECORDING_STARTED; diff --git a/ui/admin/tests/unit/controllers/scopes/scope/session-recordings/session-recording/channels-by-connection/index-test.js b/ui/admin/tests/unit/controllers/scopes/scope/session-recordings/session-recording/channels-by-connection/index-test.js new file mode 100644 index 000000000..b28e1e4e7 --- /dev/null +++ b/ui/admin/tests/unit/controllers/scopes/scope/session-recordings/session-recording/channels-by-connection/index-test.js @@ -0,0 +1,104 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'admin/tests/helpers'; +import { + STATE_SESSION_RECORDING_AVAILABLE, + STATE_SESSION_RECORDING_STARTED, + STATE_SESSION_RECORDING_UNKNOWN, +} from 'api/models/session-recording'; + +module( + 'Unit | Controller | scopes/scope/session-recordings/session-recording/channels-by-connection/index', + function (hooks) { + setupTest(hooks); + + test('isSessionInprogressWithNoConnections returns true if session has started with no connections', function (assert) { + const store = this.owner.lookup('service:store'); + const controller = this.owner.lookup( + 'controller:scopes/scope/session-recordings/session-recording/channels-by-connection/index' + ); + + const sessionRecording = store.createRecord('session-recording', { + state: STATE_SESSION_RECORDING_STARTED, + connection_recordings: [], + }); + controller.set('model', { sessionRecording }); + + assert.true(controller.isSessionInprogressWithNoConnections); + }); + + test('isSessionInprogressWithNoConnections returns false if session has started and has connections', function (assert) { + const store = this.owner.lookup('service:store'); + const controller = this.owner.lookup( + 'controller:scopes/scope/session-recordings/session-recording/channels-by-connection/index' + ); + + const sessionRecording = store.createRecord('session-recording', { + state: STATE_SESSION_RECORDING_STARTED, + connection_recordings: [store.createRecord('connection-recording')], + }); + controller.set('model', { sessionRecording }); + + assert.false(controller.isSessionInprogressWithNoConnections); + }); + + test('isSessionInprogressWithNoConnections returns false if session is complete and has connections', function (assert) { + const store = this.owner.lookup('service:store'); + const controller = this.owner.lookup( + 'controller:scopes/scope/session-recordings/session-recording/channels-by-connection/index' + ); + + const sessionRecording = store.createRecord('session-recording', { + state: STATE_SESSION_RECORDING_AVAILABLE, + connection_recordings: [store.createRecord('connection-recording')], + }); + controller.set('model', { sessionRecording }); + + assert.false(controller.isSessionInprogressWithNoConnections); + }); + + test('isSessionUnknownWithNoConnections returns true if session is unknown with no connections', function (assert) { + const store = this.owner.lookup('service:store'); + const controller = this.owner.lookup( + 'controller:scopes/scope/session-recordings/session-recording/channels-by-connection/index' + ); + + const sessionRecording = store.createRecord('session-recording', { + state: STATE_SESSION_RECORDING_UNKNOWN, + connection_recordings: [], + }); + controller.set('model', { sessionRecording }); + + assert.true(controller.isSessionUnknownWithNoConnections); + }); + + test('isSessionUnknownWithNoConnections returns false if session is unknown and has connections', function (assert) { + const store = this.owner.lookup('service:store'); + const controller = this.owner.lookup( + 'controller:scopes/scope/session-recordings/session-recording/channels-by-connection/index' + ); + + const sessionRecording = store.createRecord('session-recording', { + state: STATE_SESSION_RECORDING_UNKNOWN, + connection_recordings: [store.createRecord('connection-recording')], + }); + controller.set('model', { sessionRecording }); + + assert.false(controller.isSessionUnknownWithNoConnections); + }); + + test('isSessionUnknownWithNoConnections returns false if session is complete and has connections', function (assert) { + const store = this.owner.lookup('service:store'); + const controller = this.owner.lookup( + 'controller:scopes/scope/session-recordings/session-recording/channels-by-connection/index' + ); + + const sessionRecording = store.createRecord('session-recording', { + state: STATE_SESSION_RECORDING_AVAILABLE, + connection_recordings: [store.createRecord('connection-recording')], + }); + controller.set('model', { sessionRecording }); + + assert.false(controller.isSessionUnknownWithNoConnections); + }); + } +); From 998df395603b324447fa5a74143a5a9cae9bed58 Mon Sep 17 00:00:00 2001 From: Randall Morey Date: Tue, 30 May 2023 10:37:35 -0700 Subject: [PATCH 183/193] =?UTF-8?q?fix:=20=F0=9F=90=9B=20scopeModel=20shou?= =?UTF-8?q?ld=20check=20for=20ID=20before=20calling=20peekRecord=20(#298)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- addons/api/addon/models/base.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/api/addon/models/base.js b/addons/api/addon/models/base.js index 6ba189d5e..3084f7bf4 100644 --- a/addons/api/addon/models/base.js +++ b/addons/api/addon/models/base.js @@ -57,7 +57,7 @@ export default class BaseModel extends Model { get scopeModel() { const id = this.scopeID; - return this.store.peekRecord('scope', id); + return id ? this.store.peekRecord('scope', id) : null; } // Ember seems to have a bug with its internals and can't correctly set From 55b1ea7350b7e7dcdbfba233d1c347637733f450 Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Corvo Date: Tue, 30 May 2023 13:15:04 -0700 Subject: [PATCH 184/193] Change start_time for created_time (#297) * Change started_time for created_time for session details within channels by connection --- addons/core/translations/form/en-us.yaml | 2 ++ .../scopes/scope/session-recordings/index.hbs | 2 +- .../channels-by-connection/index.hbs | 12 +++++++----- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/addons/core/translations/form/en-us.yaml b/addons/core/translations/form/en-us.yaml index 9d76fa1f4..26605561d 100644 --- a/addons/core/translations/form/en-us.yaml +++ b/addons/core/translations/form/en-us.yaml @@ -173,3 +173,5 @@ tags: secret-editor: details: This secret is saved but won't be displayed edit: Click to replace this secret +created: + label: Created diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs index 25b171216..a35eaa3c2 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs @@ -23,7 +23,7 @@ > <:body as |B|> - {{! Time }} + {{! Created Time }} {{#if B.data.created_time}} diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/index.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/index.hbs index 6ec4cfc0d..6d13a1a89 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/index.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/index.hbs @@ -168,16 +168,18 @@ /> {{/if}} - {{! Start time }} - {{#if @model.sessionRecording.start_time}} + {{! Created time }} + {{#if @model.sessionRecording.created_time}} - {{t 'form.started.label'}} + {{t 'form.created.label'}} {{/if}} From 2cd4995c9219b14c5a2bc30ed278759cb363d992 Mon Sep 17 00:00:00 2001 From: Randall Morey Date: Wed, 31 May 2023 11:28:27 -0700 Subject: [PATCH 185/193] Feature worker recording storage path (#299) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: πŸ’‘ refactor worker form fieldset to use HDS * feat: 🎸 add recording_storage_path optional config for workers * chore: πŸ€– tweak language and add learn-more link * chore: πŸ€– add additional feature check * Update addons/core/translations/resources/en-us.yaml Co-authored-by: Zhihe Li * chore: πŸ€– use hds inline link --------- Co-authored-by: Zhihe Li --- addons/core/translations/resources/en-us.yaml | 8 +++ .../form/worker/create-worker-led/index.hbs | 52 ++++++++++++++++--- .../form/worker/create-worker-led/index.js | 17 +++++- ui/admin/config/environment.js | 1 + 4 files changed, 70 insertions(+), 8 deletions(-) diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml index 3833ad15a..fb38da18c 100644 --- a/addons/core/translations/resources/en-us.yaml +++ b/addons/core/translations/resources/en-us.yaml @@ -718,6 +718,14 @@ worker: worker_tags: label: Worker Tags help: Boundary can use tags to define key-value pairs which targets can use to determine where they should route connections. + local_session_recording_storage: + label: Local Session Recording Storage + help: To record sessions using this worker, specify a local storage path and ensure that it is provisioned with sufficient capacity. In progress recordings are stored locally until they complete, and then moved to the remote storage bucket associated with their target. + enable_recording_storage_path: + label: Enable Recording Storage + recording_storage_path: + label: Recording Storage Path + help: Local path on the worker node for temporary file storage. steps: 1: title: 1. Configure your new worker diff --git a/ui/admin/app/components/form/worker/create-worker-led/index.hbs b/ui/admin/app/components/form/worker/create-worker-led/index.hbs index 5ed7d7fbc..9dc167d24 100644 --- a/ui/admin/app/components/form/worker/create-worker-led/index.hbs +++ b/ui/admin/app/components/form/worker/create-worker-led/index.hbs @@ -51,12 +51,12 @@ /> {{/if}} - - <:title>{{t 'resources.worker.form.worker_tags.label'}} - <:description>{{t + + {{t 'resources.worker.form.worker_tags.label'}} + {{t 'resources.worker.form.worker_tags.help' - }} - <:body> + }} + {{#each this.workerTags as |tag index|}} @@ -108,8 +108,46 @@ - - + + + + {{#if (feature-flag 'ssh-session-recording')}} + + {{t + 'resources.worker.form.local_session_recording_storage.label' + }} + + {{t 'resources.worker.form.local_session_recording_storage.help'}} + {{t + 'actions.learn-more' + }} + + + + {{t + 'resources.worker.form.enable_recording_storage_path.label' + }} + + + {{#if this.enableRecordingStoragePath}} + + + + {{/if}} + + {{/if}} diff --git a/ui/admin/app/components/form/worker/create-worker-led/index.js b/ui/admin/app/components/form/worker/create-worker-led/index.js index 355f9ab64..256880988 100644 --- a/ui/admin/app/components/form/worker/create-worker-led/index.js +++ b/ui/admin/app/components/form/worker/create-worker-led/index.js @@ -33,6 +33,8 @@ export default class FormWorkerCreateWorkerLedComponent extends Component { @tracked workerTags = A([]); @tracked newWorkerKey; @tracked newWorkerValue; + @tracked enableRecordingStoragePath = false; + @tracked recording_storage_path = ''; get clusterIDFromURL() { const hostname = this.window?.location?.hostname; @@ -55,6 +57,14 @@ export default class FormWorkerCreateWorkerLedComponent extends Component { touch ${this.configFilePath || ''}/pki-worker.hcl`; } + get recordingStoragePathText() { + const path = this.recording_storage_path || ''; + return this.features.isEnabled('ssh-session-recording') && + this.enableRecordingStoragePath + ? `\n recording_storage_path = "${path}"` + : ''; + } + /** * Returns config creation text for ``. The user will see * different outputs based on if they are using `hcp` or `oss` binaries. @@ -93,7 +103,7 @@ worker { this.features.isEnabled('byow-pki-hcp-cluster-id') ? `${tagsText}` : `${tagsText}${upstreamText}` - } + }${this.recordingStoragePathText} }`; if (this.features.isEnabled('byow-pki-hcp-cluster-id')) { @@ -187,4 +197,9 @@ unzip *.zip ;\\ removeWorkerTagByIndex(index) { this.workerTags.removeAt(index); } + + @action + toggleEnableRecordingStoragePath() { + this.enableRecordingStoragePath = !this.enableRecordingStoragePath; + } } diff --git a/ui/admin/config/environment.js b/ui/admin/config/environment.js index 17df14226..d5d47ed8e 100644 --- a/ui/admin/config/environment.js +++ b/ui/admin/config/environment.js @@ -104,6 +104,7 @@ module.exports = function (environment) { 'worker.manage-workers': '/workers/manage-workers-on-hcp', 'worker-filters': '/worker-filters', 'storage-bucket': '/storage-buckets', + 'session-recording': '/session-recordings', }, }, From 4ac6259d2a82aeaf035a6e601357c536d9670070 Mon Sep 17 00:00:00 2001 From: Zhihe Li Date: Wed, 31 May 2023 15:27:30 -0400 Subject: [PATCH 186/193] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Fix=20isAsciicast?= =?UTF-8?q?=20check=20(#301)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit βœ… Closes: ICU-9511 --- addons/api/addon/models/channel-recording.js | 2 +- .../api/tests/unit/models/channel-recording-test.js | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/addons/api/addon/models/channel-recording.js b/addons/api/addon/models/channel-recording.js index c1696f9f0..eb35df41b 100644 --- a/addons/api/addon/models/channel-recording.js +++ b/addons/api/addon/models/channel-recording.js @@ -11,7 +11,7 @@ export default class ChannelRecordingModel extends GeneratedChannelRecordingMode * @type {boolean} */ get isAsciicast() { - return this.mime_types.includes(MIME_TYPE_ASCIICAST); + return this.mime_types?.includes(MIME_TYPE_ASCIICAST) ?? false; } /** diff --git a/addons/api/tests/unit/models/channel-recording-test.js b/addons/api/tests/unit/models/channel-recording-test.js index 9cf91b116..7ee3ced5b 100644 --- a/addons/api/tests/unit/models/channel-recording-test.js +++ b/addons/api/tests/unit/models/channel-recording-test.js @@ -23,4 +23,17 @@ module('Unit | Model | channel-recording', function (hooks) { assert.true(modelA.isAsciicast); assert.false(modelB.isAsciicast); }); + + test('it has isAsciicast property and returns the expected values when mime_types are not present', async function (assert) { + assert.expect(2); + const store = this.owner.lookup('service:store'); + const modelA = store.createRecord('channel-recording', { + mime_types: undefined, + }); + const modelB = store.createRecord('channel-recording', { + mime_types: [], + }); + assert.false(modelA.isAsciicast); + assert.false(modelB.isAsciicast); + }); }); From 63c6d24363451a27ee19b9d2ca4ad09f5380180c Mon Sep 17 00:00:00 2001 From: Cameron Perera Date: Wed, 31 May 2023 15:01:12 -0500 Subject: [PATCH 187/193] =?UTF-8?q?fix:=20=F0=9F=90=9B=20add=20message=20f?= =?UTF-8?q?or=20channels=20that=20cannot=20be=20played=20back=20(#302)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: πŸ› Fix isAsciicast check βœ… Closes: ICU-9511 * fix: πŸ› add message for channels that cannot be played back * Update ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs Co-authored-by: Zhihe Li * refactor: πŸ’‘ update not supported message --------- Co-authored-by: Zhihe Li --- addons/core/translations/resources/en-us.yaml | 3 ++ .../channels-by-connection/channel.hbs | 44 ++++++++++++------- 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml index fb38da18c..089f2dd42 100644 --- a/addons/core/translations/resources/en-us.yaml +++ b/addons/core/translations/resources/en-us.yaml @@ -252,6 +252,9 @@ session-recording: title: We can't play back this channel because the file is missing description: This likely means the connected storage bucket is misconfigured or the file was deleted. link: Retrieving lost session recordings + not-supported: + title: Playback is not supported for this channel + description: The contents of this channel cannot be replayed. player: back-navigation: Back to channels session: diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs index 3786d0d3a..4c014e10e 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs @@ -36,7 +36,7 @@ {{#if (can 'getAsciicast channel-recording' @model.channelRecording) }} - {{! Was not able to downlaod asciicast }} + {{! Was not able to download asciicast }} {{else}} - {{! Not authorized to downlaod asciicast }} - - + {{#if @model.channelRecording.isAsciicast}} + {{! Not authorized to download asciicast }} + + + {{else}} + {{! Playback not supported }} + + + {{/if}} {{/if}} {{/if}} From d130a019d7a2add3448ad60cb1bc4536c878cc93 Mon Sep 17 00:00:00 2001 From: Cameron Perera Date: Wed, 31 May 2023 18:36:37 -0500 Subject: [PATCH 188/193] =?UTF-8?q?refactor:=20=F0=9F=92=A1=20update=20to?= =?UTF-8?q?=20new=20filesize=20package=20and=20output=20format=20(#306)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/addon/helpers/format-bytes-size.js | 4 +- addons/core/package.json | 2 +- .../helpers/format-bytes-size-test.js | 12 +- yarn.lock | 104 +++++++++--------- 4 files changed, 65 insertions(+), 57 deletions(-) diff --git a/addons/core/addon/helpers/format-bytes-size.js b/addons/core/addon/helpers/format-bytes-size.js index 339b62e51..ef4b46c02 100644 --- a/addons/core/addon/helpers/format-bytes-size.js +++ b/addons/core/addon/helpers/format-bytes-size.js @@ -1,5 +1,5 @@ import { helper } from '@ember/component/helper'; -import filesize from 'file-size'; +import { filesize } from 'filesize'; /** * Takes a int expressing file size in bytes and returns a conversion @@ -8,5 +8,5 @@ import filesize from 'file-size'; */ export default helper(function formatBytesSize([sizeInBytes]) { const numberOfBytes = Number(sizeInBytes); - return filesize(numberOfBytes).human('si'); + return filesize(numberOfBytes); }); diff --git a/addons/core/package.json b/addons/core/package.json index f7d7b8b0e..c7810f3da 100644 --- a/addons/core/package.json +++ b/addons/core/package.json @@ -41,7 +41,7 @@ "ember-intl": "^6.0.0-beta.4", "ember-loading": "^2.0.0", "ember-truth-helpers": "^3.0.0", - "file-size": "^1.0.0", + "filesize": "^10.0.7", "intl-unofficial-duration-unit-format": "^3.1.0" }, "devDependencies": { diff --git a/addons/core/tests/integration/helpers/format-bytes-size-test.js b/addons/core/tests/integration/helpers/format-bytes-size-test.js index 3f0becb59..4e5415f7b 100644 --- a/addons/core/tests/integration/helpers/format-bytes-size-test.js +++ b/addons/core/tests/integration/helpers/format-bytes-size-test.js @@ -7,7 +7,17 @@ module('Integration | Helper | format-bytes-size', function (hooks) { setupRenderingTest(hooks); test('it renders file size in human-readable string', async function (assert) { - assert.expect(16); + assert.expect(18); + // Size to B + const expectedSizeB = '1 B'; + this.set('inputNumberSizeB', 1); + this.set('inputStringSizeB', '1'); + + await render(hbs`{{format-bytes-size this.inputNumberSizeB}}`); + assert.dom(this.element).hasText(expectedSizeB); + await render(hbs`{{format-bytes-size this.inputStringSizeB}}`); + assert.dom(this.element).hasText(expectedSizeB); + // Size to kB const expectedSizeKb = '108.93 kB'; this.set('inputNumberSizeKb', 108930); diff --git a/yarn.lock b/yarn.lock index e4050a99e..27ea6c46f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10111,14 +10111,14 @@ browserify-zlib@^0.2.0: pako "~1.0.5" browserslist@4.14.2, browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.16.5, browserslist@^4.16.6, browserslist@^4.16.7, browserslist@^4.17.3, browserslist@^4.17.5, browserslist@^4.19.1, browserslist@^4.20.2, browserslist@^4.21.0, browserslist@^4.21.3: - version "4.21.5" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.5.tgz#75c5dae60063ee641f977e00edd3cfb2fb7af6a7" - integrity sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w== + version "4.21.7" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.7.tgz#e2b420947e5fb0a58e8f4668ae6e23488127e551" + integrity sha512-BauCXrQ7I2ftSqd2mvKHGo85XR0u7Ru3C/Hxsy/0TkfCtjrmAbPdzLGasmoiBxplpDXlPvdjX9u7srIMfgasNA== dependencies: - caniuse-lite "^1.0.30001449" - electron-to-chromium "^1.4.284" - node-releases "^2.0.8" - update-browserslist-db "^1.0.10" + caniuse-lite "^1.0.30001489" + electron-to-chromium "^1.4.411" + node-releases "^2.0.12" + update-browserslist-db "^1.0.11" bser@2.1.1: version "2.1.1" @@ -10407,10 +10407,10 @@ caniuse-api@^3.0.0: lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001157, caniuse-lite@^1.0.30001449: - version "1.0.30001466" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001466.tgz#c1e6197c540392e09709ecaa9e3e403428c53375" - integrity sha512-ewtFBSfWjEmxUgNBSZItFSmVtvk9zkwkl1OfRZlKA8slltRN+/C/tuGVrF9styXkN36Yu3+SeJ1qkXxDEyNZ5w== +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001157, caniuse-lite@^1.0.30001489: + version "1.0.30001492" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001492.tgz#4a06861788a52b4c81fd3344573b68cc87fe062b" + integrity sha512-2efF8SAZwgAX1FJr87KWhvuJxnGJKOnctQa8xLOskAXNXq8oiuqgl6u1kk3fFpsp3GgvzlRjiK1sl63hNtFADw== capture-exit@^2.0.0: version "2.0.0" @@ -12279,10 +12279,10 @@ electron-rebuild@^3.2.6: tar "^6.0.5" yargs "^17.0.1" -electron-to-chromium@^1.4.284: - version "1.4.305" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.305.tgz#e4dfe3e06ab783f33171f9bde9e8ed092510fcd0" - integrity sha512-WETy6tG0CT5gm1O+xCbyapWNsCcmIvrn4NHViIGYo2AT8FV2qUCXdaB+WqYxSv/vS5mFqhBYnfZAAkVArjBmUg== +electron-to-chromium@^1.4.411: + version "1.4.415" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.415.tgz#0e17f870c0e8a0265ed37842cca5d877a741d5ec" + integrity sha512-3meOxxvyUOJVwa7cem6O2/MRPZ+FTzblSPSpG7biZoF9yOVrhCaS2l9C4jjW6YTm8uuEpmApuP0xQJSmUglfdg== element-resize-detector@^1.2.2: version "1.2.3" @@ -15013,11 +15013,6 @@ file-loader@^6.2.0: loader-utils "^2.0.0" schema-utils "^3.0.0" -file-size@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/file-size/-/file-size-1.0.0.tgz#3338267d5d206bbf60f4df60c19d7ed3813a4657" - integrity sha512-tLIdonWTpABkU6Axg2yGChYdrOsy4V8xcm0IcyAP8fSsu6jiXLm5pgs083e4sq5fzNRZuAYolUbZyYmPvCKfwQ== - file-system-cache@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/file-system-cache/-/file-system-cache-1.0.5.tgz#84259b36a2bbb8d3d6eb1021d3132ffe64cfff4f" @@ -15051,6 +15046,11 @@ filesize@6.1.0: resolved "https://registry.yarnpkg.com/filesize/-/filesize-6.1.0.tgz#e81bdaa780e2451d714d71c0d7a4f3238d37ad00" integrity sha512-LpCHtPQ3sFx67z+uh2HnSyWSLLu5Jxo21795uRDuar/EOuYWXib5EmPaGIBuSnRqH2IODiKA2k5re/K9OnN/Yg== +filesize@^10.0.7: + version "10.0.7" + resolved "https://registry.yarnpkg.com/filesize/-/filesize-10.0.7.tgz#2237a816ee60a83fd0c3382ae70800e54eced3ad" + integrity sha512-iMRG7Qo9nayLoU3PNCiLizYtsy4W1ClrapeCwEgtiQelOAOuRJiw4QaLI+sSr8xr901dgHv+EYP2bCusGZgoiA== + filesize@^4.1.2: version "4.2.1" resolved "https://registry.yarnpkg.com/filesize/-/filesize-4.2.1.tgz#ab1cb2069db5d415911c1a13e144c0e743bc89bc" @@ -16739,9 +16739,9 @@ ignore@^5.2.0: integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== immer@8.0.1, immer@^9.0.6: - version "9.0.19" - resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.19.tgz#67fb97310555690b5f9cd8380d38fc0aabb6b38b" - integrity sha512-eY+Y0qcsB4TZKwgQzLaE/lqYMlKhv5J9dyd2RhhtGhNo2njPXDqU9XPfcNfa3MIDsdtZt5KlkIsirlo4dHsWdQ== + version "9.0.21" + resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.21.tgz#1e025ea31a40f24fb064f1fef23e931496330176" + integrity sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA== immutable@^4.0.0: version "4.1.0" @@ -19779,12 +19779,10 @@ minipass@^3.1.0, minipass@^3.1.3: dependencies: yallist "^4.0.0" -minipass@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-4.0.0.tgz#7cebb0f9fa7d56f0c5b17853cbe28838a8dbbd3b" - integrity sha512-g2Uuh2jEKoht+zvO6vJqXmYpflPqzRBT+Th2h01DKh5z7wbY/AZ2gCQ78cP70YoHPyFdY30YBV5WxgLOEwOykw== - dependencies: - yallist "^4.0.0" +minipass@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-5.0.0.tgz#3e9788ffb90b694a5d0ec94479a45b5d8738133d" + integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== minizlib@^2.0.0, minizlib@^2.1.1: version "2.1.2" @@ -19946,9 +19944,9 @@ nan@^2.12.1: integrity sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ== nanoid@^3.1.31, nanoid@^3.3.4: - version "3.3.4" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab" - integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw== + version "3.3.6" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.6.tgz#443380c856d6e9f9824267d960b4236ad583ea4c" + integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA== nanomatch@^1.2.9: version "1.2.13" @@ -20048,9 +20046,9 @@ node-dir@^0.1.17: minimatch "^3.0.2" node-fetch@^2.6.0, node-fetch@^2.6.1, node-fetch@^2.6.7: - version "2.6.9" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.9.tgz#7c7f744b5cc6eb5fd404e0c7a9fec630a55657e6" - integrity sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg== + version "2.6.11" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.11.tgz#cde7fc71deef3131ef80a738919f999e6edfff25" + integrity sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w== dependencies: whatwg-url "^5.0.0" @@ -20131,10 +20129,10 @@ node-notifier@^10.0.0, node-notifier@^8.0.1: uuid "^8.3.0" which "^2.0.2" -node-releases@^2.0.8: - version "2.0.10" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.10.tgz#c311ebae3b6a148c89b1813fd7c4d3c024ef537f" - integrity sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w== +node-releases@^2.0.12: + version "2.0.12" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.12.tgz#35627cc224a23bfb06fb3380f2b3afaaa7eb1039" + integrity sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ== node-watch@0.7.3: version "0.7.3" @@ -23282,9 +23280,9 @@ shebang-regex@^3.0.0: integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== shell-quote@1.7.2, shell-quote@^1.6.1, shell-quote@^1.7.3: - version "1.8.0" - resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.0.tgz#20d078d0eaf71d54f43bd2ba14a1b5b9bfa5c8ba" - integrity sha512-QHsz8GgQIGKlRi24yFc6a6lN69Idnx634w49ay6+jA5yFh7a1UY+4Rp6HPx/L/1zcEDPEij8cIsiqR6bQsE5VQ== + version "1.8.1" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.1.tgz#6dbf4db75515ad5bac63b4f1894c3a154c766680" + integrity sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA== shelljs@^0.8.4, shelljs@^0.8.5: version "0.8.5" @@ -24458,13 +24456,13 @@ tapable@^2.1.1, tapable@^2.2.0: integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== tar@^6.0.2, tar@^6.0.5, tar@^6.1.0, tar@^6.1.2, tar@^6.1.9: - version "6.1.13" - resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.13.tgz#46e22529000f612180601a6fe0680e7da508847b" - integrity sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw== + version "6.1.15" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.15.tgz#c9738b0b98845a3b344d334b8fa3041aaba53a69" + integrity sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A== dependencies: chownr "^2.0.0" fs-minipass "^2.0.0" - minipass "^4.0.0" + minipass "^5.0.0" minizlib "^2.1.1" mkdirp "^1.0.3" yallist "^4.0.0" @@ -24573,9 +24571,9 @@ terser-webpack-plugin@^5.1.3: terser "^5.7.2" terser@^4.1.2, terser@^4.6.3, terser@^5.14.2, terser@^5.3.0, terser@^5.3.4, terser@^5.7.2: - version "5.16.6" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.16.6.tgz#f6c7a14a378ee0630fbe3ac8d1f41b4681109533" - integrity sha512-IBZ+ZQIA9sMaXmRZCUMDjNH0D5AQQfdn4WUjHL0+1lF4TP1IHRJbrhb6fNaXWikrYQTSkb7SLxkeXAiy1p7mbg== + version "5.17.6" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.17.6.tgz#d810e75e1bb3350c799cd90ebefe19c9412c12de" + integrity sha512-V8QHcs8YuyLkLHsJO5ucyff1ykrLVsR4dNnS//L5Y3NiSXpbK1J+WMVUs67eI0KTxs9JtHhgEQpXQVHlHI92DQ== dependencies: "@jridgewell/source-map" "^0.3.2" acorn "^8.5.0" @@ -25359,10 +25357,10 @@ upath@^2.0.1: resolved "https://registry.yarnpkg.com/upath/-/upath-2.0.1.tgz#50c73dea68d6f6b990f51d279ce6081665d61a8b" integrity sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w== -update-browserslist-db@^1.0.10: - version "1.0.10" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz#0f54b876545726f17d00cd9a2561e6dade943ff3" - integrity sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ== +update-browserslist-db@^1.0.11: + version "1.0.11" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz#9a2a641ad2907ae7b3616506f4b977851db5b940" + integrity sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA== dependencies: escalade "^3.1.1" picocolors "^1.0.0" From e36ee56de18779d1979a229ff87d2037dc37ea2a Mon Sep 17 00:00:00 2001 From: Zhihe Li Date: Wed, 31 May 2023 20:13:56 -0400 Subject: [PATCH 189/193] Merge from main (#305) Merge from main --- .../api/addon/generated/models/auth-method.js | 2 +- addons/api/addon/generated/models/target.js | 13 +++++ addons/api/addon/models/target.js | 6 --- .../api/mirage/generated/factories/target.js | 1 + .../unit/serializers/auth-method-test.js | 49 +++++++++++++++++++ .../api/tests/unit/serializers/target-test.js | 6 +++ addons/core/translations/form/en-us.yaml | 3 -- addons/core/translations/resources/en-us.yaml | 6 +++ .../form/host-catalog/aws/index.hbs | 2 +- .../form/host-catalog/azure/index.hbs | 2 +- .../form/host-catalog/static/index.hbs | 26 ---------- .../components/form/target/details/index.hbs | 27 +++++++++- 12 files changed, 103 insertions(+), 40 deletions(-) diff --git a/addons/api/addon/generated/models/auth-method.js b/addons/api/addon/generated/models/auth-method.js index 85ef9fe24..eeef31ec0 100644 --- a/addons/api/addon/generated/models/auth-method.js +++ b/addons/api/addon/generated/models/auth-method.js @@ -61,7 +61,7 @@ export default class GeneratedAuthMethodModel extends BaseModel { @attr('string', { isNestedAttribute: true }) client_id; - @attr('string', { isNestedAttribute: true }) client_secret; + @attr('string', { isNestedAttribute: true, isSecret: true }) client_secret; @attr('string', { readOnly: true, isNestedAttribute: true }) client_secret_hmac; diff --git a/addons/api/addon/generated/models/target.js b/addons/api/addon/generated/models/target.js index 19ee4b2f3..d363a9d03 100644 --- a/addons/api/addon/generated/models/target.js +++ b/addons/api/addon/generated/models/target.js @@ -84,6 +84,19 @@ export default class GeneratedTargetModel extends BaseModel { }) address; + @attr('number', { + isNestedAttribute: true, + description: 'The default port a target should use if present.', + }) + default_port; + + @attr('number', { + isNestedAttribute: true, + description: + "The default port that will be listened on by the client's local proxy.", + }) + default_client_port; + @attr('string', { description: 'The storage bucket associated with this target.', isNestedAttribute: true, diff --git a/addons/api/addon/models/target.js b/addons/api/addon/models/target.js index ae5060563..ec7b12e4e 100644 --- a/addons/api/addon/models/target.js +++ b/addons/api/addon/models/target.js @@ -18,12 +18,6 @@ export default class TargetModel extends GeneratedTargetModel { // =attributes - @attr('number', { - isNestedAttribute: true, - description: 'The default port a target should use if present.', - }) - default_port; - /** * @type Array */ diff --git a/addons/api/mirage/generated/factories/target.js b/addons/api/mirage/generated/factories/target.js index cf868541a..f551efda2 100644 --- a/addons/api/mirage/generated/factories/target.js +++ b/addons/api/mirage/generated/factories/target.js @@ -17,5 +17,6 @@ export default Factory.extend({ updated_time: () => faker.date.recent(), disabled: () => faker.datatype.boolean(), default_port: () => faker.datatype.number(), + default_client_port: () => faker.datatype.number(), version: () => faker.datatype.number(), }); diff --git a/addons/api/tests/unit/serializers/auth-method-test.js b/addons/api/tests/unit/serializers/auth-method-test.js index f9989a5f3..c38bd0e56 100644 --- a/addons/api/tests/unit/serializers/auth-method-test.js +++ b/addons/api/tests/unit/serializers/auth-method-test.js @@ -89,6 +89,55 @@ module('Unit | Serializer | auth method', function (hooks) { }); }); + test("it doesn't serialize client secrets when not set", function (assert) { + assert.expect(1); + let store = this.owner.lookup('service:store'); + let record = store.createRecord('auth-method', { + type: TYPE_AUTH_METHOD_OIDC, + name: 'OIDC Auth Method', + state: 'foo', + account_claim_maps: [{ from: 'foo', to: 'bar' }], + claims_scopes: [{ value: 'profile' }, { value: 'email' }], + signing_algorithms: [{ value: 'RS256' }, { value: 'RS384' }], + allowed_audiences: [ + { value: 'www.alice.com' }, + { value: 'www.alice.com/admin' }, + ], + idp_ca_certs: [ + { value: 'certificate-1234' }, + { value: 'certificate-5678' }, + ], + api_url_prefix: 'protocol://host:port/foo', + client_id: 'id123', + client_secret: null, + disable_discovered_config_validation: true, + dry_run: true, + issuer: 'http://www.example.net', + max_age: 500, + }); + + let serializedRecord = record.serialize(); + + assert.deepEqual(serializedRecord, { + type: TYPE_AUTH_METHOD_OIDC, + name: 'OIDC Auth Method', + description: null, + attributes: { + account_claim_maps: ['foo=bar'], + claims_scopes: ['profile', 'email'], + signing_algorithms: ['RS256', 'RS384'], + allowed_audiences: ['www.alice.com', 'www.alice.com/admin'], + idp_ca_certs: ['certificate-1234', 'certificate-5678'], + api_url_prefix: 'protocol://host:port/foo', + client_id: 'id123', + disable_discovered_config_validation: true, + dry_run: true, + issuer: 'http://www.example.net', + max_age: 500, + }, + }); + }); + test('it serializes OIDC records with only state and version when `adapterOptions.state` is passed', function (assert) { assert.expect(1); const store = this.owner.lookup('service:store'); diff --git a/addons/api/tests/unit/serializers/target-test.js b/addons/api/tests/unit/serializers/target-test.js index 676dde493..6b1fe308d 100644 --- a/addons/api/tests/unit/serializers/target-test.js +++ b/addons/api/tests/unit/serializers/target-test.js @@ -31,6 +31,7 @@ module('Unit | Serializer | target', function (hooks) { type: 'org', }, default_port: 1234, + default_client_port: 4321, version: 1, type: TYPE_TARGET_TCP, address: '0.0.0.0', @@ -51,6 +52,7 @@ module('Unit | Serializer | target', function (hooks) { ingress_worker_filter: null, attributes: { default_port: 1234, + default_client_port: 4321, enable_session_recording: false, storage_bucket_id: null, }, @@ -160,6 +162,7 @@ module('Unit | Serializer | target', function (hooks) { ingress_worker_filter: null, attributes: { default_port: 1234, + default_client_port: null, enable_session_recording: true, storage_bucket_id: 'bucketID', }, @@ -197,6 +200,7 @@ module('Unit | Serializer | target', function (hooks) { ingress_worker_filter: null, attributes: { default_port: 1234, + default_client_port: null, enable_session_recording: false, storage_bucket_id: null, }, @@ -234,6 +238,7 @@ module('Unit | Serializer | target', function (hooks) { ingress_worker_filter: null, attributes: { default_port: 1234, + default_client_port: null, enable_session_recording: false, storage_bucket_id: null, }, @@ -271,6 +276,7 @@ module('Unit | Serializer | target', function (hooks) { ingress_worker_filter: 'ingress worker', attributes: { default_port: 1234, + default_client_port: null, enable_session_recording: false, storage_bucket_id: null, }, diff --git a/addons/core/translations/form/en-us.yaml b/addons/core/translations/form/en-us.yaml index 26605561d..7c2236ef1 100644 --- a/addons/core/translations/form/en-us.yaml +++ b/addons/core/translations/form/en-us.yaml @@ -33,9 +33,6 @@ grant: address: label: Address help: An IP, host name, or other routable address -default_port: - label: Default Port - help: The default port on which to connect current_password: label: Current Password new_password: diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml index 089f2dd42..4ada52c62 100644 --- a/addons/core/translations/resources/en-us.yaml +++ b/addons/core/translations/resources/en-us.yaml @@ -434,6 +434,12 @@ target: worker_filter: label: Worker Filter help: Deprecated. Boolean expression to filter the workers that are allowed to satisfy this request. + default_port: + label: Default Port + help: The default port on which to connect. + default_client_port: + label: Default Client Port + help: The local proxy port on which to listen by default when a session is started on a client. sidebar: label: Session Recording help: Record SSH sessions on this target and save them to an Amazon S3 bucket. diff --git a/ui/admin/app/components/form/host-catalog/aws/index.hbs b/ui/admin/app/components/form/host-catalog/aws/index.hbs index ceb9c1838..abfbb5401 100644 --- a/ui/admin/app/components/form/host-catalog/aws/index.hbs +++ b/ui/admin/app/components/form/host-catalog/aws/index.hbs @@ -69,7 +69,7 @@ {{/each}} - + {{t 'titles.provider'}} {{t 'titles.choose-a-provider'}} {{t 'descriptions.choose-a-provider'}} diff --git a/ui/admin/app/components/form/host-catalog/azure/index.hbs b/ui/admin/app/components/form/host-catalog/azure/index.hbs index 51f1bc29c..238a3e334 100644 --- a/ui/admin/app/components/form/host-catalog/azure/index.hbs +++ b/ui/admin/app/components/form/host-catalog/azure/index.hbs @@ -68,7 +68,7 @@ {{/each}} - + {{t 'titles.provider'}} {{t 'titles.choose-a-provider'}} {{concat diff --git a/ui/admin/app/components/form/host-catalog/static/index.hbs b/ui/admin/app/components/form/host-catalog/static/index.hbs index 42ea38589..23bed2624 100644 --- a/ui/admin/app/components/form/host-catalog/static/index.hbs +++ b/ui/admin/app/components/form/host-catalog/static/index.hbs @@ -71,32 +71,6 @@ {{/each}} - - {{#if @model.isPlugin}} - - - {{t 'titles.provider'}} - {{t 'titles.choose-a-provider'}} - {{t 'descriptions.choose-a-provider'}} - - {{#each-in this.mapResourceTypeWithIcon as |pluginType|}} - - {{t - (concat 'resources.host-catalog.types.' pluginType) - }} - {{t - (concat 'resources.host-catalog.help.' pluginType) - }} - - {{/each-in}} - - {{/if}} {{/if}} {{#if (can 'save model' @model)}} diff --git a/ui/admin/app/components/form/target/details/index.hbs b/ui/admin/app/components/form/target/details/index.hbs index 824d9f7de..91e247e64 100644 --- a/ui/admin/app/components/form/target/details/index.hbs +++ b/ui/admin/app/components/form/target/details/index.hbs @@ -123,9 +123,9 @@ as |F| > {{t - 'form.default_port.label' + 'resources.target.form.default_port.label' }} - {{t 'form.default_port.help'}} + {{t 'resources.target.form.default_port.help'}} {{#if @model.errors.default_port}} {{#each @model.errors.default_port as |error|}} @@ -135,6 +135,29 @@ {{/if}} + + {{t 'resources.target.form.default_client_port.label'}} + {{t + 'resources.target.form.default_client_port.help' + }} + {{#if @model.errors.default_client_port}} + + {{#each @model.errors.default_client_port as |error|}} + {{error.message}} + {{/each}} + + {{/if}} + + Date: Thu, 1 Jun 2023 10:15:38 -0400 Subject: [PATCH 190/193] =?UTF-8?q?refactor:=20=F0=9F=92=A1=20Add=20loadin?= =?UTF-8?q?g=20substate=20for=20channels=20(#303)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: πŸ’‘ Add loading substate for channels * refactor: πŸ’‘ Use conditional block for session recording player * style: πŸ’„ Use a unicode ellipsis instead of periods * refactor: πŸ’‘ rename asciiCast to asciicast (#307) --------- Co-authored-by: cameronperera --- addons/api/mirage/config.js | 4 +- addons/api/mirage/data/asciicasts.js | 6 +- addons/core/translations/resources/en-us.yaml | 1 + .../session-recording/player/index.hbs | 10 +++- ui/admin/app/routes/application.js | 12 ---- .../channels-by-connection/channel.js | 17 ++---- .../channels-by-connection/channel/index.js | 29 ++++++++++ ui/admin/app/styles/app.scss | 9 +++ .../channels-by-connection/channel.hbs | 55 +------------------ .../channels-by-connection/channel/index.hbs | 48 ++++++++++++++++ .../channel/loading.hbs | 9 +++ .../session-recording/player-test.js | 2 +- .../channel/index-test.js | 16 ++++++ 13 files changed, 131 insertions(+), 87 deletions(-) create mode 100644 ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel/index.js create mode 100644 ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel/index.hbs create mode 100644 ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel/loading.hbs create mode 100644 ui/admin/tests/unit/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel/index-test.js diff --git a/addons/api/mirage/config.js b/addons/api/mirage/config.js index 25be61159..c3bdda3f7 100644 --- a/addons/api/mirage/config.js +++ b/addons/api/mirage/config.js @@ -15,7 +15,7 @@ import { pickRandomStatusString } from './factories/session'; import initializeMockIPC from './scenarios/ipc'; import makeBooleanFilter from './helpers/bexpr-filter'; import { faker } from '@faker-js/faker'; -import { asciiCasts } from './data/asciicasts'; +import { asciicasts } from './data/asciicasts'; const isTesting = environmentConfig.environment === 'test'; @@ -725,7 +725,7 @@ function routes() { const method = idMethod.split(':')[1]; if (method === 'download') { - return faker.helpers.arrayElement(asciiCasts); + return faker.helpers.arrayElement(asciicasts); } else { return sessionRecordings.find(id); } diff --git a/addons/api/mirage/data/asciicasts.js b/addons/api/mirage/data/asciicasts.js index 99ce39286..478913dc7 100644 --- a/addons/api/mirage/data/asciicasts.js +++ b/addons/api/mirage/data/asciicasts.js @@ -1,4 +1,4 @@ -export const asciiCast1 = `{"version": 2, "width": 124, "height": 36, "timestamp": 1670352594, "env": {"SHELL": "/bin/zsh", "TERM": "xterm-256color"}} +export const asciicast1 = `{"version": 2, "width": 124, "height": 36, "timestamp": 1670352594, "env": {"SHELL": "/bin/zsh", "TERM": "xterm-256color"}} [2.138652, "o", "\\u001b[1m\\u001b[7m%\\u001b[27m\\u001b[1m\\u001b[0m \\r \\r\\u001b]2;ember-asciinema-player\\u0007\\u001b]1;..iinema-player\\u0007"] [2.220877, "o", "\\r\\u001b[0m\\u001b[27m\\u001b[24m\\u001b[J\\u001b[33member-asciinema-player\\u001b[00m \\u001b[32mgit\\u001b[00m:\\u001b[36m(main*)\\u001b[00m $ \\u001b[K"] [2.221019, "o", "\\u001b[?1h\\u001b="] @@ -68,7 +68,7 @@ export const asciiCast1 = `{"version": 2, "width": 124, "height": 36, "timestamp [16.52863, "o", "\\u001b[?2004h"] [19.078794, "o", "\\u001b[?2004l\\r\\r\\n"]`; -export const asciiCast2 = `{"version": 2, "width": 112, "height": 30, "timestamp": 1672793720, "env": {"SHELL": "/bin/bash", "TERM": "xterm-256color"}} +export const asciicast2 = `{"version": 2, "width": 112, "height": 30, "timestamp": 1672793720, "env": {"SHELL": "/bin/bash", "TERM": "xterm-256color"}} [0.036928, "o", "\\u001b[?2004h\\u001b[1;32m[\\u001b]0;johan@nixos: ~/src/hashicorp/boundary-enterprise\\u0007johan@nixos:~/src/hashicorp/boundary-enterprise]$\\u001b[0m "] [2.827983, "o", "b"] [2.9386, "o", "o"] @@ -148,4 +148,4 @@ export const asciiCast2 = `{"version": 2, "width": 112, "height": 30, "timestamp [21.303896, "o", "\\r\\n"] [21.307902, "o", "\\u001b[?2004l\\rexit\\r\\n"]`; -export const asciiCasts = [asciiCast1, asciiCast2]; +export const asciicasts = [asciicast1, asciicast2]; diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml index 4ada52c62..6065a103e 100644 --- a/addons/core/translations/resources/en-us.yaml +++ b/addons/core/translations/resources/en-us.yaml @@ -257,6 +257,7 @@ session-recording: description: The contents of this channel cannot be replayed. player: back-navigation: Back to channels + loading: Loading recording… session: title: Session Playback form: diff --git a/ui/admin/app/components/session-recording/player/index.hbs b/ui/admin/app/components/session-recording/player/index.hbs index d8850e80f..80a9f85f8 100644 --- a/ui/admin/app/components/session-recording/player/index.hbs +++ b/ui/admin/app/components/session-recording/player/index.hbs @@ -8,7 +8,11 @@ @model={{@model}} />
    -
    - -
    + {{#if (has-block)}} + {{yield}} + {{else}} +
    + +
    + {{/if}}
    \ No newline at end of file diff --git a/ui/admin/app/routes/application.js b/ui/admin/app/routes/application.js index cbdbc109e..137527b1a 100644 --- a/ui/admin/app/routes/application.js +++ b/ui/admin/app/routes/application.js @@ -7,7 +7,6 @@ import Route from '@ember/routing/route'; import { getOwner } from '@ember/application'; import { inject as service } from '@ember/service'; import { action } from '@ember/object'; -import { loading } from 'ember-loading'; import { A } from '@ember/array'; /** @@ -75,17 +74,6 @@ export default class ApplicationRoute extends Route { this.session.invalidate(); } - /** - * Hooks into ember-loading to kick off loading indicator in the - * application template. - * @return {boolean} always returns true - */ - @action - @loading - loading() { - return true; - } - /** * Invalidates the session if a 401 error occurs and returns false to * prevent further error handling. diff --git a/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.js b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.js index 5736d68c1..60dd486cb 100644 --- a/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.js +++ b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.js @@ -4,33 +4,26 @@ import { inject as service } from '@ember/service'; export default class ScopesScopeSessionRecordingsSessionRecordingChannelsByConnectionChannelRoute extends Route { // =services @service store; - @service can; // =methods /** * - * @param {*} channel_id - * @returns {channelRecording: Object, sessionRecording: Object, storageBucket: Object, asciicast: Object} + * @param {string} channel_id + * @returns {channelRecording: Object, sessionRecording: Object, storageBucket: Object} */ - async model({ channel_id }) { - let asciicast; - const { sessionRecording, storageBucket } = await this.modelFor( + model({ channel_id }) { + const { sessionRecording, storageBucket } = this.modelFor( 'scopes.scope.session-recordings.session-recording.channels-by-connection' ); - const channelRecording = await this.store.peekRecord( + const channelRecording = this.store.peekRecord( 'channel-recording', channel_id ); - if (this.can.can('getAsciicast channel-recording', channelRecording)) { - asciicast = await channelRecording.getAsciicast(); - } - return { channelRecording, sessionRecording, storageBucket, - asciicast, }; } } diff --git a/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel/index.js b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel/index.js new file mode 100644 index 000000000..18d552c72 --- /dev/null +++ b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel/index.js @@ -0,0 +1,29 @@ +import Route from '@ember/routing/route'; +import { inject as service } from '@ember/service'; + +export default class ScopesScopeSessionRecordingsSessionRecordingChannelsByConnectionChannelIndexRoute extends Route { + // =services + @service can; + + // =methods + /** + * @returns {channelRecording: Object, sessionRecording: Object, storageBucket: Object, asciicast: Object} + */ + async model() { + let asciicast; + const { sessionRecording, storageBucket, channelRecording } = this.modelFor( + 'scopes.scope.session-recordings.session-recording.channels-by-connection.channel' + ); + + if (this.can.can('getAsciicast channel-recording', channelRecording)) { + asciicast = await channelRecording.getAsciicast(); + } + + return { + channelRecording, + sessionRecording, + storageBucket, + asciicast, + }; + } +} diff --git a/ui/admin/app/styles/app.scss b/ui/admin/app/styles/app.scss index 63db717cf..24162d53c 100644 --- a/ui/admin/app/styles/app.scss +++ b/ui/admin/app/styles/app.scss @@ -800,6 +800,15 @@ } } + &-loading { + color: var(--token-color-palette-neutral-400); + display: flex; + gap: 1rem; + justify-content: center; + align-items: center; + height: 75vh; + } + &-theme { .asciinema-theme-asciinema { background-color: var(--player-background-color); diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs index 4c014e10e..f6b5ce31f 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs @@ -25,60 +25,7 @@ - {{#if @model.asciicast}} - - {{else}} - - {{#if - (can 'getAsciicast channel-recording' @model.channelRecording) - }} - {{! Was not able to download asciicast }} - - - {{else}} - {{#if @model.channelRecording.isAsciicast}} - {{! Not authorized to download asciicast }} - - - {{else}} - {{! Playback not supported }} - - - {{/if}} - {{/if}} - - {{/if}} + {{outlet}} diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel/index.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel/index.hbs new file mode 100644 index 000000000..3ac73d930 --- /dev/null +++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel/index.hbs @@ -0,0 +1,48 @@ +{{#if @model.asciicast}} + +{{else}} + + {{#if (can 'getAsciicast channel-recording' @model.channelRecording)}} + {{! Was not able to download asciicast }} + + + {{else}} + {{#if @model.channelRecording.isAsciicast}} + {{! Not authorized to download asciicast }} + + + {{else}} + {{! Playback not supported }} + + + {{/if}} + {{/if}} + +{{/if}} \ No newline at end of file diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel/loading.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel/loading.hbs new file mode 100644 index 000000000..2918ed16a --- /dev/null +++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel/loading.hbs @@ -0,0 +1,9 @@ + +
    + + {{t 'resources.session-recording.channel.player.loading'}} +
    +
    \ No newline at end of file diff --git a/ui/admin/tests/integration/components/session-recording/player-test.js b/ui/admin/tests/integration/components/session-recording/player-test.js index d299706a7..0a8415298 100644 --- a/ui/admin/tests/integration/components/session-recording/player-test.js +++ b/ui/admin/tests/integration/components/session-recording/player-test.js @@ -28,7 +28,7 @@ module('Integration | Component | session-recording/player', function (hooks) { [3.63678, "o", "t"]`; await render(hbs` - + `); assert.dom('.session-recording-player-header').hasText('Back to channels'); diff --git a/ui/admin/tests/unit/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel/index-test.js b/ui/admin/tests/unit/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel/index-test.js new file mode 100644 index 000000000..432ccb9e2 --- /dev/null +++ b/ui/admin/tests/unit/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel/index-test.js @@ -0,0 +1,16 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'admin/tests/helpers'; + +module( + 'Unit | Route | scopes/scope/session-recordings/session-recording/channels-by-connection/channel/index', + function (hooks) { + setupTest(hooks); + + test('it exists', function (assert) { + let route = this.owner.lookup( + 'route:scopes/scope/session-recordings/session-recording/channels-by-connection/channel/index' + ); + assert.ok(route); + }); + } +); From 8200c37842f58bc7ae47baa26920d5fb3f1d4b13 Mon Sep 17 00:00:00 2001 From: Randall Morey Date: Thu, 1 Jun 2023 09:37:23 -0700 Subject: [PATCH 191/193] =?UTF-8?q?chore:=20=F0=9F=A4=96=20add=20resource?= =?UTF-8?q?=20descriptions=20(#308)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- addons/core/translations/resources/en-us.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml index 6065a103e..ae4e0d79a 100644 --- a/addons/core/translations/resources/en-us.yaml +++ b/addons/core/translations/resources/en-us.yaml @@ -216,6 +216,7 @@ org: session-recording: title: Session Recording title_plural: Session Recordings + description: Protocol-aware recordings capture data and actions during user sessions. Operators may review recordings for auditing and analysis. details: Session details related: Related up: '{bytes} up' @@ -279,6 +280,7 @@ session-recording: storage-bucket: title: Storage Bucket title_plural: Storage Buckets + description: External services store data from session recordings. messages: none: title: No storage buckets yet From 06cd27f9746afd1e5e3b307d3bb3ba03d282cc93 Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Corvo Date: Thu, 1 Jun 2023 11:52:07 -0700 Subject: [PATCH 192/193] Stop using format-date-iso-human which avoids T and timezone to use format-date-iso which includes T and TZ (#312) --- .../app/templates/scopes/scope/session-recordings/index.hbs | 2 +- .../session-recording/channels-by-connection/channel.hbs | 2 +- .../session-recording/channels-by-connection/index.hbs | 4 +--- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs index a35eaa3c2..69955f6f4 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs @@ -28,7 +28,7 @@ {{#if B.data.created_time}} {{/if}} diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs index f6b5ce31f..c7a3729b4 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs @@ -42,7 +42,7 @@ @model.channelRecording.start_time }} > - {{format-date-iso-human @model.channelRecording.start_time}} + {{format-date-iso @model.channelRecording.start_time}} {{/if}} diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/index.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/index.hbs index 6d13a1a89..241b99768 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/index.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/index.hbs @@ -177,9 +177,7 @@ @model.sessionRecording.created_time }} > - {{format-date-iso-human - @model.sessionRecording.created_time - }} + {{format-date-iso @model.sessionRecording.created_time}} {{/if}} From 97c95153d37d99025b9e9402dc0300a5440be58d Mon Sep 17 00:00:00 2001 From: Dharini Jeeva Date: Thu, 1 Jun 2023 12:32:52 -0700 Subject: [PATCH 193/193] =?UTF-8?q?chore:=20=F0=9F=A4=96=20add=20descripti?= =?UTF-8?q?on=20and=20doc=20link=20(#311)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/templates/scopes/scope/session-recordings/index.hbs | 5 ++++- .../app/templates/scopes/scope/storage-buckets/index.hbs | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs index 69955f6f4..979ca6eda 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/index.hbs @@ -4,7 +4,10 @@ -

    {{t 'resources.session-recording.title_plural'}}

    +

    {{t 'resources.session-recording.title_plural'}} + +

    +

    {{t 'resources.session-recording.description'}}

    diff --git a/ui/admin/app/templates/scopes/scope/storage-buckets/index.hbs b/ui/admin/app/templates/scopes/scope/storage-buckets/index.hbs index 8050b81b0..0b71a2252 100644 --- a/ui/admin/app/templates/scopes/scope/storage-buckets/index.hbs +++ b/ui/admin/app/templates/scopes/scope/storage-buckets/index.hbs @@ -9,11 +9,11 @@ - {{! TODO: Add valid doc link and description}}

    {{t 'resources.storage-bucket.title_plural'}}

    +

    {{t 'resources.storage-bucket.description'}}