Merge Boundary UI OSS branch 'main' at commit 7350c0e08
This commit is contained in:
commit
b91c706948
38 files changed
+359
-322
No files matched your search
@@ -35,6 +35,21 @@ function routes() {
|
||||
|
||||
// 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
|
||||
|
||||
@@ -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.*"
|
||||
|
||||
@@ -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.*"
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
"qunit": "^2.19.1",
|
||||
"qunit-dom": "^2.0.0",
|
||||
"rose": "*",
|
||||
"webpack": "^5.72.1"
|
||||
"webpack": "^5.76.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "12.* || 14.* || 16.*"
|
||||
|
||||
@@ -47,3 +47,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
|
||||
@@ -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
|
||||
|
||||
@@ -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.*"
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
+18
-1
@@ -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 });
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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|}}
|
||||
<dropdown.item>
|
||||
<radioGroup.radio
|
||||
@label={{t (concat 'editions.' edition)}}
|
||||
@label={{edition}}
|
||||
@value={{edition}}
|
||||
/>
|
||||
</dropdown.item>
|
||||
@@ -97,6 +97,20 @@
|
||||
</form.radioGroup>
|
||||
</Rose::Form>
|
||||
</dropdown.section>
|
||||
<dropdown.separator />
|
||||
<dropdown.section @title={{t 'actions.toggle-licensed-features'}}>
|
||||
<Rose::Form as |form|>
|
||||
{{#each this.featureEdition.licensedFeatures as |feature|}}
|
||||
<dropdown.item>
|
||||
<form.checkbox
|
||||
@label={{feature}}
|
||||
@checked={{feature-flag feature}}
|
||||
@onChange={{route-action 'toggleFeature' feature}}
|
||||
/>
|
||||
</dropdown.item>
|
||||
{{/each}}
|
||||
</Rose::Form>
|
||||
</dropdown.section>
|
||||
</utilities.dropdown>
|
||||
{{/if}}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
</page.actions>
|
||||
|
||||
<page.navigation>
|
||||
<HostCatalogs::HostCatalog::Hosts::Host::Navigation @model={{@model}} />
|
||||
<HostCatalogs::HostCatalog::Hosts::Host::Navigation />
|
||||
</page.navigation>
|
||||
|
||||
<page.body>
|
||||
|
||||
@@ -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,
|
||||
@@ -98,8 +113,7 @@ module.exports = function (environment) {
|
||||
timeout: 4000,
|
||||
},
|
||||
|
||||
selectedEdition: features.selectedEdition,
|
||||
featureEditions: features.featureEditions,
|
||||
features: features,
|
||||
featureFlags: {},
|
||||
};
|
||||
|
||||
@@ -125,14 +139,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') {
|
||||
@@ -150,16 +166,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') {
|
||||
|
||||
+17
-15
@@ -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,
|
||||
@@ -27,7 +40,6 @@ featureEditions.oss = {
|
||||
};
|
||||
featureEditions.enterprise = {
|
||||
...featureEditions.oss,
|
||||
'ssh-target': true,
|
||||
'target-worker-filters-v2-ingress': true,
|
||||
'vault-worker-filter': true,
|
||||
};
|
||||
@@ -37,18 +49,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,
|
||||
};
|
||||
@@ -100,7 +100,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.*"
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
});
|
||||
@@ -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();
|
||||
});
|
||||
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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('/');
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
});
|
||||
@@ -74,6 +74,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);
|
||||
@@ -132,23 +134,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');
|
||||
@@ -161,6 +162,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');
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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');
|
||||
});
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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`<WorkerDiagram />`);
|
||||
|
||||
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`<WorkerDiagram />`);
|
||||
|
||||
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`<WorkerDiagram />`);
|
||||
|
||||
assert.true(featuresService.isEnabled(targetWorkerFilterIngress));
|
||||
assert.true(featuresService.isEnabled(targetWorkerFilterHCP));
|
||||
assert
|
||||
.dom('[data-test-dual-filter-hcp-egress-off-ingress-off]')
|
||||
.isVisible();
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
|
||||
Executable → Regular
+1
-1
@@ -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.*"
|
||||
|
||||
@@ -7300,14 +7300,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"
|
||||
@@ -7332,12 +7324,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==
|
||||
@@ -8117,26 +8104,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"
|
||||
@@ -8249,7 +8221,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==
|
||||
@@ -8259,16 +8231,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"
|
||||
@@ -9531,7 +9493,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==
|
||||
@@ -10515,9 +10477,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"
|
||||
@@ -11864,7 +11826,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=
|
||||
@@ -14069,7 +14031,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==
|
||||
@@ -14077,14 +14039,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"
|
||||
@@ -16309,12 +16263,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, 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==
|
||||
@@ -17000,7 +16949,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 +19080,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 +19093,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 +19112,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 +19337,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==
|
||||
@@ -20128,15 +20094,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==
|
||||
@@ -20152,36 +20110,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==
|
||||
@@ -20432,14 +20371,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==
|
||||
@@ -21028,6 +20960,7 @@ npm@~6.14.6:
|
||||
cmd-shim "^3.0.3"
|
||||
columnify "~1.5.4"
|
||||
config-chain "^1.1.13"
|
||||
debuglog "*"
|
||||
detect-indent "~5.0.0"
|
||||
detect-newline "^2.1.0"
|
||||
dezalgo "^1.0.4"
|
||||
@@ -21042,6 +20975,7 @@ npm@~6.14.6:
|
||||
has-unicode "~2.0.1"
|
||||
hosted-git-info "^2.8.9"
|
||||
iferr "^1.0.2"
|
||||
imurmurhash "*"
|
||||
infer-owner "^1.0.4"
|
||||
inflight "~1.0.6"
|
||||
inherits "^2.0.4"
|
||||
@@ -21060,8 +20994,14 @@ npm@~6.14.6:
|
||||
libnpx "^10.2.4"
|
||||
lock-verify "^2.2.2"
|
||||
lockfile "^1.0.4"
|
||||
lodash._baseindexof "*"
|
||||
lodash._baseuniq "~4.6.0"
|
||||
lodash._bindcallback "*"
|
||||
lodash._cacheindexof "*"
|
||||
lodash._createcache "*"
|
||||
lodash._getnative "*"
|
||||
lodash.clonedeep "~4.5.0"
|
||||
lodash.restparam "*"
|
||||
lodash.union "~4.6.0"
|
||||
lodash.uniq "~4.5.0"
|
||||
lodash.without "~4.4.0"
|
||||
@@ -25597,9 +25537,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"
|
||||
@@ -26799,15 +26739,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==
|
||||
@@ -26884,11 +26816,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"
|
||||
@@ -26930,40 +26857,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"
|
||||
@@ -26990,36 +26887,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"
|
||||
|
||||
Reference in new issue
Block a user