mirror of
				https://github.com/optim-enterprises-bv/vault.git
				synced 2025-11-03 20:17:59 +00:00 
			
		
		
		
	Update ui dependencies (#7244)
* be more specific about node version, and specify a yarn version * update ember, ember-cli, ember-data, ember-data-model-fragments * use router handlers to access transition information * fix shadowing of component helper * update ivy-codemirror, ember-cli-inject-live-reload * remove custom router service * don't use transition.queryParams * update ember-cli-deprecation-workflow * refactor kv v1 to use 'path' instead of 'id' on creation * fix auth-jwt-test and toolbar-link-test * update ember composable helpers * remove Ember.copy from test file * no more deprecations in the workflow * fix more secret tests * fix remaining failed tests * move select component to core because it's used by ttl-picker * generate new model class for each test instead of reusing an existing one * fix selectors on kmip tests * refactor how control groups construct urls from the new transition objects * add router service override back in, and have it be evented so that we can trigger router events on it * move stories and markdown files to core if the component lives in core * update ember-cli, ember-cli-babel, ember-auto-import * update base64js, date-fns, deepmerge, codemirror, broccoli-asset-rev * update linting rules * fix test selectors * update ember-api-actions, ember-concurrency, ember-load-initializers, escape-string-regexp, normalize.css, prettier-eslint-cli, jsdoc-to-markdown * remove test-results dir * update base64js, ember-cli-clipboard, ember-cli-sass, ember-cli-string-helpers, ember-cli-template-lint, ember-cli-uglify, ember-link-action * fix linting * run yarn install without restoring from cache * refactor how tests are run and handle the vault server subprocess * update makefile for new test task names * update circle config to use the new yarn task * fix writing the seal keys when starting the dev server * remove optional deps from the lockfile * don't ignore-optional on yarn install * remove errant console.log * update ember-basic-dropdown-hover, jsonlint, yargs-parser * update ember-cli-flash * add back optionalDeps * update @babel/core@7.5.5, ember-basic-dropdown@1.1.3, eslint-plugin-ember@6.8.2 * update storybook to the latest release * add a babel config with targets so that the ember babel plugin works properly * update ember-resolver, move ember-cli-storybook to devDependencies * revert normalize.css upgrade * silence fetchadapter warning for now * exclude 3rd party array helper now that ember includes one * fix switch and entity lookup styling * only add -root suffix if it's not in versions mode * make sure drop always has an array on the aws role form * fix labels like we did with the backport * update eslintignore * update the yarn version in the docker build file * update eslint ignore
This commit is contained in:
		
							
								
								
									
										4
									
								
								.circleci/config.yml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										4
									
								
								.circleci/config.yml
									
									
									
										generated
									
									
									
								
							@@ -130,7 +130,7 @@ jobs:
 | 
			
		||||
          # Run Ember tests
 | 
			
		||||
          cd ui
 | 
			
		||||
          mkdir -p test-results/qunit
 | 
			
		||||
          yarn run test-oss
 | 
			
		||||
          yarn test:oss
 | 
			
		||||
        name: Test UI
 | 
			
		||||
    - store_artifacts:
 | 
			
		||||
        path: ui/test-results
 | 
			
		||||
@@ -561,7 +561,7 @@ workflows:
 | 
			
		||||
#           # Run Ember tests
 | 
			
		||||
#           cd ui
 | 
			
		||||
#           mkdir -p test-results/qunit
 | 
			
		||||
#           yarn run test-oss
 | 
			
		||||
#           yarn test:oss
 | 
			
		||||
#         name: Test UI
 | 
			
		||||
#     - store_artifacts:
 | 
			
		||||
#         path: ui/test-results
 | 
			
		||||
 
 | 
			
		||||
@@ -26,7 +26,7 @@ steps:
 | 
			
		||||
        # Run Ember tests
 | 
			
		||||
        cd ui
 | 
			
		||||
        mkdir -p test-results/qunit
 | 
			
		||||
        yarn run test-oss
 | 
			
		||||
        yarn test:oss
 | 
			
		||||
  - store_artifacts:
 | 
			
		||||
      path: ui/test-results
 | 
			
		||||
  - store_test_results:
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										12
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								Makefile
									
									
									
									
									
								
							@@ -142,9 +142,9 @@ static-assets:
 | 
			
		||||
 | 
			
		||||
test-ember:
 | 
			
		||||
	@echo "--> Installing JavaScript assets"
 | 
			
		||||
	@cd ui && yarn --ignore-optional
 | 
			
		||||
	@cd ui && yarn
 | 
			
		||||
	@echo "--> Running ember tests"
 | 
			
		||||
	@cd ui && yarn run test-oss
 | 
			
		||||
	@cd ui && yarn run test:oss
 | 
			
		||||
 | 
			
		||||
ember-ci-test: # Deprecated, to be removed soon.
 | 
			
		||||
	@echo "ember-ci-test is deprecated in favour of test-ui-browserstack"
 | 
			
		||||
@@ -161,13 +161,13 @@ check-browserstack-creds:
 | 
			
		||||
 | 
			
		||||
test-ui-browserstack: check-vault-in-path check-browserstack-creds
 | 
			
		||||
	@echo "--> Installing JavaScript assets"
 | 
			
		||||
	@cd ui && yarn --ignore-optional
 | 
			
		||||
	@cd ui && yarn
 | 
			
		||||
	@echo "--> Running ember tests in Browserstack"
 | 
			
		||||
	@cd ui && yarn run test:browserstack
 | 
			
		||||
 | 
			
		||||
ember-dist:
 | 
			
		||||
	@echo "--> Installing JavaScript assets"
 | 
			
		||||
	@cd ui && yarn --ignore-optional
 | 
			
		||||
	@cd ui && yarn
 | 
			
		||||
	@cd ui && npm rebuild node-sass
 | 
			
		||||
	@echo "--> Building Ember application"
 | 
			
		||||
	@cd ui && yarn run build
 | 
			
		||||
@@ -175,10 +175,10 @@ ember-dist:
 | 
			
		||||
 | 
			
		||||
ember-dist-dev:
 | 
			
		||||
	@echo "--> Installing JavaScript assets"
 | 
			
		||||
	@cd ui && yarn --ignore-optional
 | 
			
		||||
	@cd ui && yarn
 | 
			
		||||
	@cd ui && npm rebuild node-sass
 | 
			
		||||
	@echo "--> Building Ember application"
 | 
			
		||||
	@cd ui && yarn run build-dev
 | 
			
		||||
	@cd ui && yarn run build:dev
 | 
			
		||||
 | 
			
		||||
static-dist: ember-dist static-assets
 | 
			
		||||
static-dist-dev: ember-dist-dev static-assets
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,7 @@ RUN curl -sL https://deb.nodesource.com/setup_10.x | bash -
 | 
			
		||||
RUN curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
 | 
			
		||||
RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
 | 
			
		||||
 | 
			
		||||
RUN apt-get update -y && apt-get install -y -q nodejs yarn=1.12.1-1
 | 
			
		||||
RUN apt-get update -y && apt-get install -y -q nodejs yarn=1.17.3
 | 
			
		||||
 | 
			
		||||
RUN rm -rf /var/lib/apt/lists/*
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -8,6 +8,8 @@
 | 
			
		||||
 | 
			
		||||
# dependencies
 | 
			
		||||
/bower_components/
 | 
			
		||||
/node_modules/
 | 
			
		||||
/.storybook/
 | 
			
		||||
/stories/
 | 
			
		||||
 | 
			
		||||
# misc
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,4 @@
 | 
			
		||||
// env: node
 | 
			
		||||
module.exports = {
 | 
			
		||||
  parser: 'babel-eslint',
 | 
			
		||||
  root: true,
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										26
									
								
								ui/.storybook/babel.config.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								ui/.storybook/babel.config.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
			
		||||
module.exports = {
 | 
			
		||||
  presets: [
 | 
			
		||||
    [
 | 
			
		||||
      '@babel/preset-env',
 | 
			
		||||
      {
 | 
			
		||||
        shippedProposals: true,
 | 
			
		||||
        useBuiltIns: 'usage',
 | 
			
		||||
        corejs: '3',
 | 
			
		||||
        targets: ['last 1 Chrome versions', 'last 1 Firefox versions', 'last 1 Safari versions'],
 | 
			
		||||
      },
 | 
			
		||||
    ],
 | 
			
		||||
  ],
 | 
			
		||||
  plugins: [
 | 
			
		||||
    [
 | 
			
		||||
      '@babel/plugin-proposal-decorators',
 | 
			
		||||
      {
 | 
			
		||||
        legacy: true,
 | 
			
		||||
      },
 | 
			
		||||
    ],
 | 
			
		||||
    ['@babel/plugin-proposal-class-properties', { loose: true }],
 | 
			
		||||
    '@babel/plugin-syntax-dynamic-import',
 | 
			
		||||
    ['@babel/plugin-proposal-object-rest-spread', { loose: true, useBuiltIns: true }],
 | 
			
		||||
    'babel-plugin-macros',
 | 
			
		||||
    ['emotion', { sourceMap: true, autoLabel: true }],
 | 
			
		||||
  ],
 | 
			
		||||
};
 | 
			
		||||
@@ -1,7 +1,6 @@
 | 
			
		||||
import { configure, addParameters, addDecorator } from '@storybook/ember';
 | 
			
		||||
import { INITIAL_VIEWPORTS } from '@storybook/addon-viewport';
 | 
			
		||||
import theme from './theme.js';
 | 
			
		||||
import { assign } from '@ember/polyfills';
 | 
			
		||||
 | 
			
		||||
function loadStories() {
 | 
			
		||||
  // automatically import all files ending in *.stories.js
 | 
			
		||||
@@ -28,7 +27,7 @@ addDecorator(storyFn => {
 | 
			
		||||
 | 
			
		||||
  // Create a div to wrap the Canvas tab with the applied styles.
 | 
			
		||||
  const element = document.createElement('div');
 | 
			
		||||
  assign(element.style, styles.style);
 | 
			
		||||
  Object.assign(element.style, styles.style);
 | 
			
		||||
 | 
			
		||||
  const innerElement = document.createElement('div');
 | 
			
		||||
  const wormhole = document.createElement('div');
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,8 @@
 | 
			
		||||
<meta name="vault/config/environment" content="%7B%22modulePrefix%22%3A%22vault%22%2C%22environment%22%3A%22development%22%2C%22rootURL%22%3A%22/ui/%22%2C%22locationType%22%3A%22auto%22%2C%22EmberENV%22%3A%7B%22FEATURES%22%3A%7B%7D%2C%22EXTEND_PROTOTYPES%22%3A%7B%22Date%22%3Afalse%7D%7D%2C%22APP%22%3A%7B%22POLLING_URLS%22%3A%5B%22sys/health%22%2C%22sys/replication/status%22%2C%22sys/seal-status%22%5D%2C%22NAMESPACE_ROOT_URLS%22%3A%5B%22sys/health%22%2C%22sys/seal-status%22%2C%22sys/license/features%22%5D%2C%22DEFAULT_PAGE_SIZE%22%3A15%2C%22LOG_TRANSITIONS%22%3Atrue%7D%2C%22flashMessageDefaults%22%3A%7B%22timeout%22%3A7000%2C%22sticky%22%3Afalse%7D%2C%22contentSecurityPolicyHeader%22%3A%22Content-Security-Policy%22%2C%22contentSecurityPolicyMeta%22%3Atrue%2C%22contentSecurityPolicy%22%3A%7B%22connect-src%22%3A%5B%22%27self%27%22%5D%2C%22img-src%22%3A%5B%22%27self%27%22%2C%22data%3A%22%5D%2C%22form-action%22%3A%5B%22%27none%27%22%5D%2C%22script-src%22%3A%5B%22%27self%27%22%5D%2C%22style-src%22%3A%5B%22%27unsafe-inline%27%22%2C%22%27self%27%22%5D%2C%22default-src%22%3A%5B%22%27none%27%22%5D%2C%22font-src%22%3A%5B%22%27self%27%22%5D%2C%22media-src%22%3A%5B%22%27self%27%22%5D%7D%2C%22emberData%22%3A%7B%22enableRecordDataRFCBuild%22%3Afalse%7D%2C%22exportApplicationGlobal%22%3Atrue%7D" />
 | 
			
		||||
<meta name="vault/config/environment" content="%7B%22modulePrefix%22%3A%22vault%22%2C%22environment%22%3A%22development%22%2C%22rootURL%22%3A%22%2Fui%2F%22%2C%22locationType%22%3A%22auto%22%2C%22EmberENV%22%3A%7B%22FEATURES%22%3A%7B%7D%2C%22EXTEND_PROTOTYPES%22%3A%7B%22Date%22%3Afalse%7D%2C%22_JQUERY_INTEGRATION%22%3Afalse%7D%2C%22APP%22%3A%7B%22POLLING_URLS%22%3A%5B%22sys%2Fhealth%22%2C%22sys%2Freplication%2Fstatus%22%2C%22sys%2Fseal-status%22%5D%2C%22NAMESPACE_ROOT_URLS%22%3A%5B%22sys%2Fhealth%22%2C%22sys%2Fseal-status%22%2C%22sys%2Flicense%2Ffeatures%22%5D%2C%22DEFAULT_PAGE_SIZE%22%3A15%2C%22LOG_TRANSITIONS%22%3Atrue%7D%2C%22flashMessageDefaults%22%3A%7B%22timeout%22%3A7000%2C%22sticky%22%3Afalse%7D%2C%22contentSecurityPolicyHeader%22%3A%22Content-Security-Policy%22%2C%22contentSecurityPolicyMeta%22%3Atrue%2C%22contentSecurityPolicy%22%3A%7B%22connect-src%22%3A%5B%22'self'%22%5D%2C%22img-src%22%3A%5B%22'self'%22%2C%22data%3A%22%5D%2C%22form-action%22%3A%5B%22'none'%22%5D%2C%22script-src%22%3A%5B%22'self'%22%5D%2C%22style-src%22%3A%5B%22'unsafe-inline'%22%2C%22'self'%22%5D%2C%22default-src%22%3A%5B%22'none'%22%5D%2C%22font-src%22%3A%5B%22'self'%22%5D%2C%22media-src%22%3A%5B%22'self'%22%5D%7D%2C%22exportApplicationGlobal%22%3Atrue%7D" />
 | 
			
		||||
<meta name="kmip/config/environment" content="%7B%22modulePrefix%22%3A%22kmip%22%2C%22environment%22%3A%22development%22%7D" />
 | 
			
		||||
<meta name="open-api-explorer/config/environment" content="%7B%22modulePrefix%22%3A%22open-api-explorer%22%2C%22environment%22%3A%22development%22%2C%22APP%22%3A%7B%22NAMESPACE_ROOT_URLS%22%3A%5B%22sys/health%22%2C%22sys/seal-status%22%2C%22sys/license/features%22%5D%7D%7D" />
 | 
			
		||||
<meta name="replication/config/environment" content="%7B%22modulePrefix%22%3A%22replication%22%2C%22environment%22%3A%22development%22%7D" />
 | 
			
		||||
<meta name="vault/config/asset-manifest" content="%7B%22bundles%22%3A%7B%22replication%22%3A%7B%22assets%22%3A%5B%7B%22uri%22%3A%22/ui/engines-dist/replication/assets/engine-vendor.js%22%2C%22type%22%3A%22js%22%7D%2C%7B%22uri%22%3A%22/ui/engines-dist/replication/assets/engine.js%22%2C%22type%22%3A%22js%22%7D%5D%7D%7D%7D" />
 | 
			
		||||
<meta name="vault/config/asset-manifest" content="%7B%22bundles%22%3A%7B%22kmip%22%3A%7B%22assets%22%3A%5B%7B%22uri%22%3A%22/ui/engines-dist/kmip/assets/engine-vendor.js%22%2C%22type%22%3A%22js%22%7D%2C%7B%22uri%22%3A%22/ui/engines-dist/kmip/assets/engine.js%22%2C%22type%22%3A%22js%22%7D%5D%7D%2C%22open-api-explorer%22%3A%7B%22assets%22%3A%5B%7B%22uri%22%3A%22/ui/engines-dist/open-api-explorer/assets/engine-vendor.css%22%2C%22type%22%3A%22css%22%7D%2C%7B%22uri%22%3A%22/ui/engines-dist/open-api-explorer/assets/engine-vendor.js%22%2C%22type%22%3A%22js%22%7D%2C%7B%22uri%22%3A%22/ui/engines-dist/open-api-explorer/assets/engine.css%22%2C%22type%22%3A%22css%22%7D%2C%7B%22uri%22%3A%22/ui/engines-dist/open-api-explorer/assets/engine.js%22%2C%22type%22%3A%22js%22%7D%5D%7D%2C%22replication%22%3A%7B%22assets%22%3A%5B%7B%22uri%22%3A%22/ui/engines-dist/replication/assets/engine-vendor.js%22%2C%22type%22%3A%22js%22%7D%2C%7B%22uri%22%3A%22/ui/engines-dist/replication/assets/engine.js%22%2C%22type%22%3A%22js%22%7D%5D%7D%7D%7D" />
 | 
			
		||||
<link rel="stylesheet" href="/assets/vendor.css" />
 | 
			
		||||
<link rel="stylesheet" href="/assets/vault.css" />
 | 
			
		||||
<link rel="icon" href="/favicon.png" />
 | 
			
		||||
 
 | 
			
		||||
@@ -9,8 +9,11 @@ export default ApplicationAdapter.extend({
 | 
			
		||||
    const serializer = store.serializerFor(type.modelName);
 | 
			
		||||
    const data = serializer.serialize(snapshot);
 | 
			
		||||
    const { id } = snapshot;
 | 
			
		||||
 | 
			
		||||
    return this.ajax(this.urlForSecret(snapshot.attr('backend'), id), 'POST', { data });
 | 
			
		||||
    const path = snapshot.record.path;
 | 
			
		||||
    return this.ajax(this.urlForSecret(snapshot.attr('backend'), path || id), 'POST', { data }).then(() => {
 | 
			
		||||
      data.id = path || id;
 | 
			
		||||
      return data;
 | 
			
		||||
    });
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  createRecord() {
 | 
			
		||||
 
 | 
			
		||||
@@ -158,13 +158,10 @@ export default Component.extend(FocusOnInsertMixin, WithNavToNearestAncestor, {
 | 
			
		||||
    return this.secretDataIsAdvanced || this.preferAdvancedEdit;
 | 
			
		||||
  }),
 | 
			
		||||
 | 
			
		||||
  isWriteWithoutRead: computed(
 | 
			
		||||
    'model.{failedServerRead,selectedVersion.failedServerRead}',
 | 
			
		||||
    'isV2',
 | 
			
		||||
    function() {
 | 
			
		||||
  isWriteWithoutRead: computed('model.failedServerRead', 'modelForData.failedServerRead', 'isV2', function() {
 | 
			
		||||
    if (!this.model) return;
 | 
			
		||||
    // if the version couldn't be read from the server
 | 
			
		||||
      if (this.isV2 && this.model.selectedVersion.failedServerRead) {
 | 
			
		||||
    if (this.isV2 && this.modelForData.failedServerRead) {
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
    // if the model couldn't be read from the server
 | 
			
		||||
@@ -172,8 +169,7 @@ export default Component.extend(FocusOnInsertMixin, WithNavToNearestAncestor, {
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
    }
 | 
			
		||||
  ),
 | 
			
		||||
  }),
 | 
			
		||||
 | 
			
		||||
  transitionToRoute() {
 | 
			
		||||
    return this.router.transitionTo(...arguments);
 | 
			
		||||
@@ -307,12 +303,12 @@ export default Component.extend(FocusOnInsertMixin, WithNavToNearestAncestor, {
 | 
			
		||||
      let model = this.modelForData;
 | 
			
		||||
      // prevent from submitting if there's no key
 | 
			
		||||
      // maybe do something fancier later
 | 
			
		||||
      if (type === 'create' && isBlank(model.get('path') || model.id)) {
 | 
			
		||||
      if (type === 'create' && isBlank(model.path || model.id)) {
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      this.persistKey(() => {
 | 
			
		||||
        this.transitionToRoute(SHOW_ROUTE, this.model.id);
 | 
			
		||||
        this.transitionToRoute(SHOW_ROUTE, this.model.path || this.model.id);
 | 
			
		||||
      });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,7 @@ export function linkParams({ mode, secret, queryParams }) {
 | 
			
		||||
  let params;
 | 
			
		||||
  const route = `vault.cluster.secrets.backend.${mode}`;
 | 
			
		||||
 | 
			
		||||
  if (!secret || secret === ' ') {
 | 
			
		||||
  if ((mode !== 'versions' && !secret) || secret === ' ') {
 | 
			
		||||
    params = [route + '-root'];
 | 
			
		||||
  } else {
 | 
			
		||||
    params = [route, encodePath(secret)];
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<!DOCTYPE html lang="en">
 | 
			
		||||
<html>
 | 
			
		||||
  <head>
 | 
			
		||||
    <meta charset="utf-8">
 | 
			
		||||
 
 | 
			
		||||
@@ -5,17 +5,17 @@ import utils from 'vault/lib/key-utils';
 | 
			
		||||
export default Mixin.create({
 | 
			
		||||
  // what attribute has the path for the key
 | 
			
		||||
  // will.be 'path' for v2 or 'id' v1
 | 
			
		||||
  pathAttr: 'id',
 | 
			
		||||
  pathAttr: 'path',
 | 
			
		||||
  flags: null,
 | 
			
		||||
 | 
			
		||||
  initialParentKey: null,
 | 
			
		||||
 | 
			
		||||
  isCreating: computed('initialParentKey', function() {
 | 
			
		||||
    return this.get('initialParentKey') != null;
 | 
			
		||||
    return this.initialParentKey != null;
 | 
			
		||||
  }),
 | 
			
		||||
 | 
			
		||||
  pathVal() {
 | 
			
		||||
    return this.get(this.pathAttr);
 | 
			
		||||
    return this[this.pathAttr] || this.id;
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  // rather than using defineProperty for all of these,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
import Mixin from '@ember/object/mixin';
 | 
			
		||||
import removeRecord from 'vault/utils/remove-record';
 | 
			
		||||
 | 
			
		||||
// removes Ember Data records from the cache when the model
 | 
			
		||||
// changes or you move away from the current route
 | 
			
		||||
@@ -10,7 +11,7 @@ export default Mixin.create({
 | 
			
		||||
    if (!model || !model.unloadRecord) {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    this.store.unloadRecord(model);
 | 
			
		||||
    removeRecord(this.store, model);
 | 
			
		||||
    model.destroy();
 | 
			
		||||
    // it's important to unset the model on the controller since controllers are singletons
 | 
			
		||||
    this.controller.set(modelPath, null);
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,7 @@ import { bool } from '@ember/object/computed';
 | 
			
		||||
const { attr, belongsTo } = DS;
 | 
			
		||||
 | 
			
		||||
export default Secret.extend({
 | 
			
		||||
  failedServerRead: attr('boolean'),
 | 
			
		||||
  pathAttr: 'path',
 | 
			
		||||
  version: attr('number'),
 | 
			
		||||
  secret: belongsTo('secret-v2'),
 | 
			
		||||
 
 | 
			
		||||
@@ -8,6 +8,7 @@ import lazyCapabilities, { apiPath } from 'vault/macros/lazy-capabilities';
 | 
			
		||||
const { attr, hasMany, belongsTo, Model } = DS;
 | 
			
		||||
 | 
			
		||||
export default Model.extend(KeyMixin, {
 | 
			
		||||
  failedServerRead: attr('boolean'),
 | 
			
		||||
  engine: belongsTo('secret-engine', { async: false }),
 | 
			
		||||
  engineId: attr('string'),
 | 
			
		||||
  versions: hasMany('secret-v2-version', { async: false, inverse: null }),
 | 
			
		||||
 
 | 
			
		||||
@@ -6,6 +6,7 @@ const { attr } = DS;
 | 
			
		||||
import lazyCapabilities, { apiPath } from 'vault/macros/lazy-capabilities';
 | 
			
		||||
 | 
			
		||||
export default DS.Model.extend(KeyMixin, {
 | 
			
		||||
  failedServerRead: attr('boolean'),
 | 
			
		||||
  auth: attr('string'),
 | 
			
		||||
  lease_duration: attr('number'),
 | 
			
		||||
  lease_id: attr('string'),
 | 
			
		||||
 
 | 
			
		||||
@@ -23,6 +23,7 @@ export default Route.extend({
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      let router = this.get('routing');
 | 
			
		||||
      //FIXME transition.intent likely needs to be replaced
 | 
			
		||||
      let errorURL = transition.intent.url;
 | 
			
		||||
      let { name, contexts, queryParams } = transition.intent;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,16 @@
 | 
			
		||||
import Route from '@ember/routing/route';
 | 
			
		||||
import { inject as service } from '@ember/service';
 | 
			
		||||
 | 
			
		||||
export default Route.extend({
 | 
			
		||||
  router: service(),
 | 
			
		||||
  init() {
 | 
			
		||||
    this._super(...arguments);
 | 
			
		||||
    this.router.on('routeWillChange', transition => {
 | 
			
		||||
      this.set('myTargetRouteName', transition.to.name);
 | 
			
		||||
    });
 | 
			
		||||
  },
 | 
			
		||||
  renderTemplate() {
 | 
			
		||||
    let { targetName } = this._router.currentState.routerJs.activeTransition;
 | 
			
		||||
    let targetName = this.myTargetRouteName;
 | 
			
		||||
    let isCallback =
 | 
			
		||||
      targetName === 'vault.cluster.oidc-callback' || targetName === 'vault.cluster.oidc-callback-namespace';
 | 
			
		||||
    if (isCallback) {
 | 
			
		||||
 
 | 
			
		||||
@@ -6,8 +6,9 @@ let secretModel = (store, backend, key) => {
 | 
			
		||||
  let backendModel = store.peekRecord('secret-engine', backend);
 | 
			
		||||
  let modelType = backendModel.get('modelTypeForKV');
 | 
			
		||||
  if (modelType !== 'secret-v2') {
 | 
			
		||||
    let model = store.createRecord(modelType);
 | 
			
		||||
    model.set('id', key);
 | 
			
		||||
    let model = store.createRecord(modelType, {
 | 
			
		||||
      path: key,
 | 
			
		||||
    });
 | 
			
		||||
    return model;
 | 
			
		||||
  }
 | 
			
		||||
  let secret = store.createRecord(modelType);
 | 
			
		||||
@@ -33,7 +34,8 @@ export default EditBase.extend({
 | 
			
		||||
      }
 | 
			
		||||
      return this.store.createRecord(modelType);
 | 
			
		||||
    }
 | 
			
		||||
    return secretModel(this.store, backend, transition.queryParams.initialKey);
 | 
			
		||||
 | 
			
		||||
    return secretModel(this.store, backend, transition.to.queryParams.initialKey);
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  model(params, transition) {
 | 
			
		||||
 
 | 
			
		||||
@@ -127,9 +127,12 @@ export default Route.extend(UnloadModelRoute, {
 | 
			
		||||
    try {
 | 
			
		||||
      if (secretModel.failedServerRead) {
 | 
			
		||||
        // we couldn't read metadata, so we want to directly fetch the version
 | 
			
		||||
        versionModel = await this.store.findRecord('secret-v2-version', JSON.stringify(versionId), {
 | 
			
		||||
 | 
			
		||||
        versionModel =
 | 
			
		||||
          this.store.peekRecord('secret-v2-version', JSON.stringify(versionId)) ||
 | 
			
		||||
          (await this.store.findRecord('secret-v2-version', JSON.stringify(versionId), {
 | 
			
		||||
            reload: true,
 | 
			
		||||
        });
 | 
			
		||||
          }));
 | 
			
		||||
      } else {
 | 
			
		||||
        // we may have previously errored, so roll it back here
 | 
			
		||||
        version.rollbackAttributes();
 | 
			
		||||
@@ -142,18 +145,20 @@ export default Route.extend(UnloadModelRoute, {
 | 
			
		||||
      if (error.httpStatus === 403 && capabilities.get('canUpdate')) {
 | 
			
		||||
        // versionModel is then a partial model from the metadata (if we have read there), or
 | 
			
		||||
        // we need to create one on the client
 | 
			
		||||
        versionModel = version || this.store.createRecord('secret-v2-version');
 | 
			
		||||
        versionModel.setProperties({
 | 
			
		||||
        if (version) {
 | 
			
		||||
          version.set('failedServerRead', true);
 | 
			
		||||
          versionModel = version;
 | 
			
		||||
        } else {
 | 
			
		||||
          this.store.push({
 | 
			
		||||
            data: {
 | 
			
		||||
              type: 'secret-v2-version',
 | 
			
		||||
              id: JSON.stringify(versionId),
 | 
			
		||||
              attributes: {
 | 
			
		||||
                failedServerRead: true,
 | 
			
		||||
              },
 | 
			
		||||
            },
 | 
			
		||||
          });
 | 
			
		||||
        // if it was created on the client we need to trigger an event via ember-data
 | 
			
		||||
        // so that it won't try to create the record on save
 | 
			
		||||
        if (versionModel.isNew) {
 | 
			
		||||
          versionModel.set('id', JSON.stringify(versionId));
 | 
			
		||||
          //TODO make this a util to better show what's happening
 | 
			
		||||
          // this is because we want the ember-data model save to call update instead of create
 | 
			
		||||
          // in the adapter so we have to force the frontend model to a "saved" state
 | 
			
		||||
          versionModel.send('pushedData');
 | 
			
		||||
          versionModel = this.store.peekRecord('secret-v2-version', JSON.stringify(versionId));
 | 
			
		||||
        }
 | 
			
		||||
      } else {
 | 
			
		||||
        throw error;
 | 
			
		||||
@@ -162,18 +167,23 @@ export default Route.extend(UnloadModelRoute, {
 | 
			
		||||
    return versionModel;
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  handleSecretModelError(capabilities, secret, modelType, error) {
 | 
			
		||||
  handleSecretModelError(capabilities, secretId, modelType, error) {
 | 
			
		||||
    // can't read the path and don't have update capability, so re-throw
 | 
			
		||||
    if (!capabilities.get('canUpdate') && modelType === 'secret') {
 | 
			
		||||
      throw error;
 | 
			
		||||
    }
 | 
			
		||||
    // don't have access to the metadata for v2 or the secret for v1,
 | 
			
		||||
    // so we make a stub model and mark it as `failedServerRead`
 | 
			
		||||
    let secretModel = this.store.createRecord(modelType);
 | 
			
		||||
    secretModel.setProperties({
 | 
			
		||||
      id: secret,
 | 
			
		||||
    this.store.push({
 | 
			
		||||
      data: {
 | 
			
		||||
        id: secretId,
 | 
			
		||||
        type: modelType,
 | 
			
		||||
        attributes: {
 | 
			
		||||
          failedServerRead: true,
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
    });
 | 
			
		||||
    let secretModel = this.store.peekRecord(modelType, secretId);
 | 
			
		||||
    return secretModel;
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,12 @@ import ApplicationSerializer from './application';
 | 
			
		||||
export default ApplicationSerializer.extend({
 | 
			
		||||
  secretDataPath: 'data',
 | 
			
		||||
  normalizeItems(payload, requestType) {
 | 
			
		||||
    if (requestType !== 'queryRecord' && payload.data.keys && Array.isArray(payload.data.keys)) {
 | 
			
		||||
    if (
 | 
			
		||||
      requestType !== 'queryRecord' &&
 | 
			
		||||
      payload.data &&
 | 
			
		||||
      payload.data.keys &&
 | 
			
		||||
      Array.isArray(payload.data.keys)
 | 
			
		||||
    ) {
 | 
			
		||||
      // if we have data.keys, it's a list of ids, so we map over that
 | 
			
		||||
      // and create objects with id's
 | 
			
		||||
      return payload.data.keys.map(secret => {
 | 
			
		||||
 
 | 
			
		||||
@@ -95,17 +95,29 @@ export default Service.extend({
 | 
			
		||||
    return RSVP.reject(error);
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  urlFromTransition(transition) {
 | 
			
		||||
    let routes = Object.keys(transition.params);
 | 
			
		||||
    let params = [];
 | 
			
		||||
    for (let route of routes) {
 | 
			
		||||
      let param = transition.params[route];
 | 
			
		||||
      if (Object.keys(param).length) {
 | 
			
		||||
        params.push(param);
 | 
			
		||||
  paramsFromTransition(transitionTo, params, queryParams) {
 | 
			
		||||
    let returnedParams = params.slice();
 | 
			
		||||
    let qps = queryParams;
 | 
			
		||||
    transitionTo.paramNames.map(name => {
 | 
			
		||||
      let param = transitionTo.params[name];
 | 
			
		||||
      if (param.length) {
 | 
			
		||||
        // push on to the front of the array since were're started at the end
 | 
			
		||||
        returnedParams.unshift(param);
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
    qps = { ...queryParams, ...transitionTo.queryParams };
 | 
			
		||||
    // if there's a parent transition, recurse to get its route params
 | 
			
		||||
    if (transitionTo.parent) {
 | 
			
		||||
      [returnedParams, qps] = this.paramsFromTransition(transitionTo.parent, returnedParams, qps);
 | 
			
		||||
    }
 | 
			
		||||
    let url = this.get('router').urlFor(transition.targetName, ...params, {
 | 
			
		||||
      queryParams: transition.queryParams,
 | 
			
		||||
    return [returnedParams, qps];
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  urlFromTransition(transitionObj) {
 | 
			
		||||
    let transition = transitionObj.to;
 | 
			
		||||
    let [params, queryParams] = this.paramsFromTransition(transition, [], {});
 | 
			
		||||
    let url = this.get('router').urlFor(transition.name, ...params, {
 | 
			
		||||
      queryParams,
 | 
			
		||||
    });
 | 
			
		||||
    return url.replace('/ui', '');
 | 
			
		||||
  },
 | 
			
		||||
 
 | 
			
		||||
@@ -144,7 +144,8 @@ export default Service.extend({
 | 
			
		||||
        return pathName.includes(k) || pathName.includes(k.replace(/\/$/, ''));
 | 
			
		||||
      });
 | 
			
		||||
      const hasMatchingPath =
 | 
			
		||||
        (matchingPath && !this.isDenied(globPaths[matchingPath])) || globPaths.hasOwnProperty('');
 | 
			
		||||
        (matchingPath && !this.isDenied(globPaths[matchingPath])) ||
 | 
			
		||||
        Object.prototype.hasOwnProperty.call(globPaths, '');
 | 
			
		||||
 | 
			
		||||
      if (matchingPath && capability) {
 | 
			
		||||
        return this.hasCapability(globPaths[matchingPath], capability) && hasMatchingPath;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,12 +1,19 @@
 | 
			
		||||
import Evented from '@ember/object/evented';
 | 
			
		||||
import Service from '@ember/service';
 | 
			
		||||
 | 
			
		||||
import { inject as service } from '@ember/service';
 | 
			
		||||
import { alias } from '@ember/object/computed';
 | 
			
		||||
 | 
			
		||||
let hasOwn = (obj, prop) => {
 | 
			
		||||
  return Object.prototype.hasOwnProperty.call(obj, prop);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export function extractRouteArgs(args) {
 | 
			
		||||
  args = args.slice();
 | 
			
		||||
  let possibleQueryParams = args[args.length - 1];
 | 
			
		||||
 | 
			
		||||
  let queryParams;
 | 
			
		||||
  if (possibleQueryParams && possibleQueryParams.hasOwnProperty('queryParams')) {
 | 
			
		||||
  if (possibleQueryParams && hasOwn(possibleQueryParams, 'queryParams')) {
 | 
			
		||||
    queryParams = args.pop().queryParams;
 | 
			
		||||
  } else {
 | 
			
		||||
    queryParams = {};
 | 
			
		||||
@@ -22,7 +29,7 @@ export function shallowEqual(a, b) {
 | 
			
		||||
  let aCount = 0;
 | 
			
		||||
  let bCount = 0;
 | 
			
		||||
  for (k in a) {
 | 
			
		||||
    if (a.hasOwnProperty(k)) {
 | 
			
		||||
    if (hasOwn(a, k)) {
 | 
			
		||||
      if (a[k] !== b[k]) {
 | 
			
		||||
        return false;
 | 
			
		||||
      }
 | 
			
		||||
@@ -31,7 +38,7 @@ export function shallowEqual(a, b) {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  for (k in b) {
 | 
			
		||||
    if (b.hasOwnProperty(k)) {
 | 
			
		||||
    if (hasOwn(b, k)) {
 | 
			
		||||
      bCount++;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
@@ -39,31 +46,43 @@ export function shallowEqual(a, b) {
 | 
			
		||||
  return aCount === bCount;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default Service.extend({
 | 
			
		||||
export default Service.extend(Evented, {
 | 
			
		||||
  init() {
 | 
			
		||||
    this._super(...arguments);
 | 
			
		||||
 | 
			
		||||
    this._router.on('routeWillChange', transition => {
 | 
			
		||||
      this.trigger('routeWillChange', transition);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    this._router.on('routeDidChange', transition => {
 | 
			
		||||
      this.trigger('routeDidChange', transition);
 | 
			
		||||
    });
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  routing: service('-routing'),
 | 
			
		||||
  router: alias('routing.router'),
 | 
			
		||||
  _router: alias('routing.router'),
 | 
			
		||||
  transitionTo() {
 | 
			
		||||
    let r = this.router;
 | 
			
		||||
    let r = this._router;
 | 
			
		||||
    return r.transitionTo.call(r, ...arguments);
 | 
			
		||||
  },
 | 
			
		||||
  replaceWith() {
 | 
			
		||||
    let r = this.router;
 | 
			
		||||
    let r = this._router;
 | 
			
		||||
    return r.replaceWith.call(r, ...arguments);
 | 
			
		||||
  },
 | 
			
		||||
  urlFor() {
 | 
			
		||||
    let r = this.router;
 | 
			
		||||
    let r = this._router;
 | 
			
		||||
    return r.generate.call(r, ...arguments);
 | 
			
		||||
  },
 | 
			
		||||
  currentURL: alias('router.currentURL'),
 | 
			
		||||
  currentRouteName: alias('router.currentRouteName'),
 | 
			
		||||
  rootURL: alias('router.rootURL'),
 | 
			
		||||
  location: alias('router.location'),
 | 
			
		||||
  currentURL: alias('_router.currentURL'),
 | 
			
		||||
  currentRouteName: alias('_router.currentRouteName'),
 | 
			
		||||
  rootURL: alias('_router.rootURL'),
 | 
			
		||||
  location: alias('_router.location'),
 | 
			
		||||
 | 
			
		||||
  //adapted from:
 | 
			
		||||
  // https://github.com/emberjs/ember.js/blob/abf753a3d494830dc9e95b1337b3654b671b11be/packages/ember-routing/lib/services/router.js#L220
 | 
			
		||||
  isActive(...args) {
 | 
			
		||||
    let { routeName, models, queryParams } = extractRouteArgs(args);
 | 
			
		||||
    let routerMicrolib = this.router._routerMicrolib;
 | 
			
		||||
    let routerMicrolib = this._router._routerMicrolib;
 | 
			
		||||
 | 
			
		||||
    if (!routerMicrolib.isActiveIntent(routeName, models, null)) {
 | 
			
		||||
      return false;
 | 
			
		||||
@@ -71,7 +90,7 @@ export default Service.extend({
 | 
			
		||||
    let hasQueryParams = Object.keys(queryParams).length > 0;
 | 
			
		||||
 | 
			
		||||
    if (hasQueryParams) {
 | 
			
		||||
      this.router._prepareQueryParams(routeName, models, queryParams, true /* fromRouterService */);
 | 
			
		||||
      this._router._prepareQueryParams(routeName, models, queryParams, true /* fromRouterService */);
 | 
			
		||||
      return shallowEqual(queryParams, routerMicrolib.state.queryParams);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -24,12 +24,12 @@
 | 
			
		||||
  .select {
 | 
			
		||||
    min-width: 190px;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
  label[for='namespace'] {
 | 
			
		||||
.toolbar-label {
 | 
			
		||||
  padding: $spacing-xs;
 | 
			
		||||
  color: $grey;
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.toolbar-scroller {
 | 
			
		||||
  align-items: center;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,6 @@
 | 
			
		||||
form {
 | 
			
		||||
  margin: 0;
 | 
			
		||||
}
 | 
			
		||||
label {
 | 
			
		||||
  cursor: pointer;
 | 
			
		||||
  &.is-select-list {
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,7 @@
 | 
			
		||||
          Multiple credential types is deprecated and you must choose one in order to save this role."
 | 
			
		||||
      />
 | 
			
		||||
    {{/if}}
 | 
			
		||||
    {{#each (if (eq mode 'edit') (drop 1 model.fields) model.fields) as |attr|}}
 | 
			
		||||
    {{#each (if (eq mode 'edit') (drop 1 (or model.fields (array))) model.fields) as |attr|}}
 | 
			
		||||
      {{form-field data-test-field attr=attr model=model}}
 | 
			
		||||
    {{/each}}
 | 
			
		||||
  </div>
 | 
			
		||||
 
 | 
			
		||||
@@ -91,7 +91,7 @@
 | 
			
		||||
{{/if}}
 | 
			
		||||
<div class="global-flash">
 | 
			
		||||
  {{#each flashMessages.queue as |flash|}}
 | 
			
		||||
    {{#flash-message data-test-flash-message=true flash=flash as |component flash close|}}
 | 
			
		||||
    {{#flash-message data-test-flash-message=true flash=flash as |customComponent flash close|}}
 | 
			
		||||
      {{#if flash.componentName}}
 | 
			
		||||
        {{component flash.componentName content=flash.content}}
 | 
			
		||||
      {{else}}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										30
									
								
								ui/app/utils/remove-record.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								ui/app/utils/remove-record.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
			
		||||
// Unlinks a record from all its relationships and unloads it from
 | 
			
		||||
// the store.
 | 
			
		||||
export default function removeRecord(store, record) {
 | 
			
		||||
  let id = record.path || record.id;
 | 
			
		||||
  if (id) {
 | 
			
		||||
    // Collect relationship property names and types
 | 
			
		||||
    const relationshipMeta = [];
 | 
			
		||||
    record.eachRelationship((key, { kind }) => {
 | 
			
		||||
      relationshipMeta.push({ key, kind });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // Push an update to this record with the relationships nulled out.
 | 
			
		||||
    // This unlinks the relationship from the models that aren't about to
 | 
			
		||||
    // be unloaded.
 | 
			
		||||
    store.push({
 | 
			
		||||
      data: {
 | 
			
		||||
        id,
 | 
			
		||||
        type: record.constructor.modelName,
 | 
			
		||||
        relationships: relationshipMeta.reduce((hash, rel) => {
 | 
			
		||||
          hash[rel.key] = { data: rel.kind === 'hasMany' ? [] : null };
 | 
			
		||||
          return hash;
 | 
			
		||||
        }, {}),
 | 
			
		||||
      },
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Now that the record has no attachments, it can be safely unloaded
 | 
			
		||||
  // from the store.
 | 
			
		||||
  store.unloadRecord(record);
 | 
			
		||||
}
 | 
			
		||||
@@ -1,11 +1,11 @@
 | 
			
		||||
/* global self */
 | 
			
		||||
self.deprecationWorkflow = self.deprecationWorkflow || {};
 | 
			
		||||
//self.deprecationWorkflow.config = {
 | 
			
		||||
//throwOnUnhandled: true
 | 
			
		||||
//}
 | 
			
		||||
self.deprecationWorkflow.config = {
 | 
			
		||||
  workflow: [
 | 
			
		||||
    // ivy-codemirror and ember-radio-button still use send-action
 | 
			
		||||
    { handler: 'silence', matchId: 'ember-component.send-action' },
 | 
			
		||||
    { handler: 'silence', matchId: 'ember-runtime.deprecate-copy-copyable' },
 | 
			
		||||
    // ember-cli-page-object uses jquery's this.$() by default - this will change when we remove jquery
 | 
			
		||||
    { handler: 'silence', matchId: 'ember-test-helpers.rendering-context.jquery-element' },
 | 
			
		||||
    // after ED 3.9 this shouldn't be necessary
 | 
			
		||||
    { handler: 'silence', matchId: 'deprecate-fetch-ember-data-support' },
 | 
			
		||||
  ],
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -23,13 +23,12 @@ module.exports = function(defaults) {
 | 
			
		||||
        return `${config.rootURL.replace(/\/$/, '')}${filePath}`;
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    codemirror: {
 | 
			
		||||
      modes: ['javascript', 'ruby'],
 | 
			
		||||
      keyMaps: ['sublime'],
 | 
			
		||||
    },
 | 
			
		||||
    babel: {
 | 
			
		||||
      plugins: ['transform-object-rest-spread'],
 | 
			
		||||
      plugins: ['@babel/plugin-proposal-object-rest-spread'],
 | 
			
		||||
    },
 | 
			
		||||
    'ember-cli-babel': {
 | 
			
		||||
      includePolyfill: isTest || isProd || isCI,
 | 
			
		||||
@@ -50,12 +49,7 @@ module.exports = function(defaults) {
 | 
			
		||||
      browsers: ['defaults', 'ie 11'],
 | 
			
		||||
    },
 | 
			
		||||
    autoImport: {
 | 
			
		||||
      webpack: {
 | 
			
		||||
        // this makes `unsafe-eval` CSP unnecessary
 | 
			
		||||
        // see https://github.com/ef4/ember-auto-import/issues/50
 | 
			
		||||
        // and https://github.com/webpack/webpack/issues/5627
 | 
			
		||||
        devtool: 'inline-source-map',
 | 
			
		||||
      },
 | 
			
		||||
      forbidEval: true,
 | 
			
		||||
    },
 | 
			
		||||
    'ember-test-selectors': {
 | 
			
		||||
      strip: isProd,
 | 
			
		||||
@@ -64,6 +58,9 @@ module.exports = function(defaults) {
 | 
			
		||||
    'ember-fetch': {
 | 
			
		||||
      preferNative: true,
 | 
			
		||||
    },
 | 
			
		||||
    'ember-composable-helpers': {
 | 
			
		||||
      except: ['array'],
 | 
			
		||||
    },
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  app.import('vendor/string-includes.js');
 | 
			
		||||
@@ -74,7 +71,7 @@ module.exports = function(defaults) {
 | 
			
		||||
  app.import('node_modules/codemirror/addon/lint/lint.css');
 | 
			
		||||
  app.import('node_modules/codemirror/addon/lint/lint.js');
 | 
			
		||||
  app.import('node_modules/codemirror/addon/lint/json-lint.js');
 | 
			
		||||
  app.import('node_modules/text-encoder-lite/index.js');
 | 
			
		||||
  app.import('node_modules/text-encoder-lite/text-encoder-lite.js');
 | 
			
		||||
 | 
			
		||||
  app.import('app/styles/bulma/bulma-radio-checkbox.css');
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
import Component from '@ember/component';
 | 
			
		||||
import layout from '../templates/components/select';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @module Select
 | 
			
		||||
@@ -21,6 +22,7 @@ import Component from '@ember/component';
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
export default Component.extend({
 | 
			
		||||
  layout,
 | 
			
		||||
  classNames: ['field'],
 | 
			
		||||
  label: null,
 | 
			
		||||
  selectedValue: null,
 | 
			
		||||
							
								
								
									
										1
									
								
								ui/lib/core/app/components/select.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								ui/lib/core/app/components/select.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
export { default } from 'core/components/select';
 | 
			
		||||
@@ -1,9 +1,7 @@
 | 
			
		||||
/* eslint-disable import/extensions */
 | 
			
		||||
import hbs from 'htmlbars-inline-precompile';
 | 
			
		||||
import { storiesOf } from '@storybook/ember';
 | 
			
		||||
import notes from './alert-banner.md';
 | 
			
		||||
import { MESSAGE_TYPES } from '../lib/core/addon/helpers/message-types.js';
 | 
			
		||||
 | 
			
		||||
import { MESSAGE_TYPES } from '../addon/helpers/message-types.js';
 | 
			
		||||
 | 
			
		||||
storiesOf('Alerts/AlertBanner/', module)
 | 
			
		||||
  .addParameters({ options: { showPanel: false } })
 | 
			
		||||
@@ -1,8 +1,7 @@
 | 
			
		||||
/* eslint-disable import/extensions */
 | 
			
		||||
import hbs from 'htmlbars-inline-precompile';
 | 
			
		||||
import { storiesOf } from '@storybook/ember';
 | 
			
		||||
import notes from './alert-inline.md';
 | 
			
		||||
import { MESSAGE_TYPES } from '../lib/core/addon/helpers/message-types.js';
 | 
			
		||||
import { MESSAGE_TYPES } from '../addon/helpers/message-types.js';
 | 
			
		||||
 | 
			
		||||
storiesOf('Alerts/AlertInline/', module)
 | 
			
		||||
  .addParameters({ options: { showPanel: false } })
 | 
			
		||||
@@ -1,14 +1,14 @@
 | 
			
		||||
/* eslint-disable import/extensions */
 | 
			
		||||
import hbs from 'htmlbars-inline-precompile';
 | 
			
		||||
import { storiesOf } from '@storybook/ember';
 | 
			
		||||
import { withKnobs, select } from '@storybook/addon-knobs';
 | 
			
		||||
import notes from './chevron.md';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
storiesOf('Chevron/', module)
 | 
			
		||||
  .addParameters({ options: { showPanel: true } })
 | 
			
		||||
  .addDecorator(withKnobs())
 | 
			
		||||
  .add(`Chevron`, () => ({
 | 
			
		||||
  .add(
 | 
			
		||||
    `Chevron`,
 | 
			
		||||
    () => ({
 | 
			
		||||
      template: hbs`
 | 
			
		||||
        <h5 class="title is-5">Chevron</h5>
 | 
			
		||||
        <Chevron @direction={{direction}} />
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
/* eslint-disable import/extensions */
 | 
			
		||||
import hbs from 'htmlbars-inline-precompile';
 | 
			
		||||
import { storiesOf } from '@storybook/ember';
 | 
			
		||||
import { withKnobs, text, boolean } from '@storybook/addon-knobs';
 | 
			
		||||
@@ -12,7 +11,8 @@ storiesOf('ConfirmAction/', module)
 | 
			
		||||
    })
 | 
			
		||||
  )
 | 
			
		||||
  .add(
 | 
			
		||||
    `ConfirmAction`, () => ({
 | 
			
		||||
    `ConfirmAction`,
 | 
			
		||||
    () => ({
 | 
			
		||||
      template: hbs`
 | 
			
		||||
        <h5 class="title is-5">Confirm Action</h5>
 | 
			
		||||
        <ConfirmAction
 | 
			
		||||
@@ -1,16 +1,16 @@
 | 
			
		||||
/* eslint-disable import/extensions */
 | 
			
		||||
import hbs from 'htmlbars-inline-precompile';
 | 
			
		||||
import { storiesOf } from '@storybook/ember';
 | 
			
		||||
import notes from './doc-link.md';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
storiesOf('DocLink/', module)
 | 
			
		||||
  .addParameters({ options: { showPanel: true } })
 | 
			
		||||
  .add(`DocLink`, () => ({
 | 
			
		||||
  .add(
 | 
			
		||||
    `DocLink`,
 | 
			
		||||
    () => ({
 | 
			
		||||
      template: hbs`
 | 
			
		||||
      <h5 class="title is-5">Doc Link</h5>
 | 
			
		||||
      <DocLink @path="/docs/secrets/kv/kv-v2.html">Learn about KV v2</DocLink>
 | 
			
		||||
    `
 | 
			
		||||
    `,
 | 
			
		||||
    }),
 | 
			
		||||
    { notes }
 | 
			
		||||
  );
 | 
			
		||||
							
								
								
									
										44
									
								
								ui/lib/core/stories/empty-state.stories.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								ui/lib/core/stories/empty-state.stories.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,44 @@
 | 
			
		||||
import hbs from 'htmlbars-inline-precompile';
 | 
			
		||||
import { storiesOf } from '@storybook/ember';
 | 
			
		||||
import { withKnobs, text } from '@storybook/addon-knobs';
 | 
			
		||||
import notes from './empty-state.md';
 | 
			
		||||
 | 
			
		||||
storiesOf('EmptyState/', module)
 | 
			
		||||
  .addParameters({ options: { showPanel: true } })
 | 
			
		||||
  .addDecorator(withKnobs({ escapeHTML: false }))
 | 
			
		||||
  .add(
 | 
			
		||||
    `EmptyState`,
 | 
			
		||||
    () => ({
 | 
			
		||||
      template: hbs`
 | 
			
		||||
      <h5 class="title is-5">Empty State</h5>
 | 
			
		||||
      <EmptyState @title={{title}} @message={{message}} />
 | 
			
		||||
    `,
 | 
			
		||||
      context: {
 | 
			
		||||
        title: text('Title', "You don't have an secrets yet"),
 | 
			
		||||
        message: text(
 | 
			
		||||
          'Message',
 | 
			
		||||
          "An explanation of why you don't have any secrets but also you maybe want to create one."
 | 
			
		||||
        ),
 | 
			
		||||
      },
 | 
			
		||||
    }),
 | 
			
		||||
    { notes }
 | 
			
		||||
  )
 | 
			
		||||
  .add(
 | 
			
		||||
    `EmptyState with content block`,
 | 
			
		||||
    () => ({
 | 
			
		||||
      template: hbs`
 | 
			
		||||
      <h5 class="title is-5">Empty State</h5>
 | 
			
		||||
      <EmptyState @title={{title}} @message={{message}}>
 | 
			
		||||
        <DocLink @path="/docs/secrets/kv/kv-v2.html">Learn about KV v2</DocLink>
 | 
			
		||||
      </EmptyState>
 | 
			
		||||
    `,
 | 
			
		||||
      context: {
 | 
			
		||||
        title: text('Title', "You don't have an secrets yet"),
 | 
			
		||||
        message: text(
 | 
			
		||||
          'Message',
 | 
			
		||||
          "An explanation of why you don't have any secrets but also you maybe want to create one."
 | 
			
		||||
        ),
 | 
			
		||||
      },
 | 
			
		||||
    }),
 | 
			
		||||
    { notes }
 | 
			
		||||
  );
 | 
			
		||||
@@ -1,8 +1,8 @@
 | 
			
		||||
/* eslint-disable import/extensions */
 | 
			
		||||
import hbs from 'htmlbars-inline-precompile';
 | 
			
		||||
import { storiesOf } from '@storybook/ember';
 | 
			
		||||
import { withKnobs, select } from '@storybook/addon-knobs';
 | 
			
		||||
import notes from './form-field-groups.md';
 | 
			
		||||
import { getOwner } from '@ember/application';
 | 
			
		||||
 | 
			
		||||
// This will need to be replaced with a fake model, since the form fields associated with
 | 
			
		||||
// each model come from OpenApi and Storybook doesn't have a Vault server to call OpenApi from.
 | 
			
		||||
@@ -37,7 +37,7 @@ storiesOf('Form/FormFieldGroups/', module)
 | 
			
		||||
      context: {
 | 
			
		||||
        actions: {
 | 
			
		||||
          getModel(modelType) {
 | 
			
		||||
            return Ember.getOwner(this)
 | 
			
		||||
            return getOwner(this)
 | 
			
		||||
              .lookup('service:store')
 | 
			
		||||
              .createRecord(`auth-config/${modelType}`);
 | 
			
		||||
          },
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
/* eslint-disable import/extensions */
 | 
			
		||||
import hbs from 'htmlbars-inline-precompile';
 | 
			
		||||
import { storiesOf } from '@storybook/ember';
 | 
			
		||||
import notes from './form-field.md';
 | 
			
		||||
@@ -1,8 +1,7 @@
 | 
			
		||||
/* eslint-disable import/extensions */
 | 
			
		||||
import hbs from 'htmlbars-inline-precompile';
 | 
			
		||||
import { storiesOf } from '@storybook/ember';
 | 
			
		||||
import notes from './icon.md';
 | 
			
		||||
import icons from '../node_modules/@hashicorp/structure-icons/dist/index.js';
 | 
			
		||||
import icons from '../../../node_modules/@hashicorp/structure-icons/dist/index.js';
 | 
			
		||||
import { withKnobs, select } from '@storybook/addon-knobs';
 | 
			
		||||
 | 
			
		||||
storiesOf('Icon/', module)
 | 
			
		||||
@@ -1,14 +1,14 @@
 | 
			
		||||
/* eslint-disable import/extensions */
 | 
			
		||||
import hbs from 'htmlbars-inline-precompile';
 | 
			
		||||
import { storiesOf } from '@storybook/ember';
 | 
			
		||||
import { withKnobs, boolean, text } from '@storybook/addon-knobs';
 | 
			
		||||
import notes from './info-table-row.md';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
storiesOf('InfoTableRow/', module)
 | 
			
		||||
  .addParameters({ options: { showPanel: true } })
 | 
			
		||||
  .addDecorator(withKnobs({ escapeHTML: false }))
 | 
			
		||||
  .add(`InfoTableRow with text value`, () => ({
 | 
			
		||||
  .add(
 | 
			
		||||
    `InfoTableRow with text value`,
 | 
			
		||||
    () => ({
 | 
			
		||||
      template: hbs`
 | 
			
		||||
      <h5 class="title is-5">Info Table Row</h5>
 | 
			
		||||
      <InfoTableRow @value={{value}} @label={{label}} @alwaysRender={{alwaysRender}} />
 | 
			
		||||
@@ -21,7 +21,9 @@ storiesOf('InfoTableRow/', module)
 | 
			
		||||
    }),
 | 
			
		||||
    { notes }
 | 
			
		||||
  )
 | 
			
		||||
  .add(`InfoTableRow with boolean value`, () => ({
 | 
			
		||||
  .add(
 | 
			
		||||
    `InfoTableRow with boolean value`,
 | 
			
		||||
    () => ({
 | 
			
		||||
      template: hbs`
 | 
			
		||||
      <h5 class="title is-5">Info Table Row</h5>
 | 
			
		||||
      <InfoTableRow @value={{value}} @label={{label}} @alwaysRender={{alwaysRender}} />
 | 
			
		||||
@@ -1,11 +1,12 @@
 | 
			
		||||
/* eslint-disable import/extensions */
 | 
			
		||||
import hbs from 'htmlbars-inline-precompile';
 | 
			
		||||
import { storiesOf } from '@storybook/ember';
 | 
			
		||||
import notes from './layout-loading.md';
 | 
			
		||||
 | 
			
		||||
storiesOf('Loading/LayoutLoading/', module)
 | 
			
		||||
  .addParameters({ options: { showPanel: true } })
 | 
			
		||||
  .add(`LayoutLoading`, () => ({
 | 
			
		||||
  .add(
 | 
			
		||||
    `LayoutLoading`,
 | 
			
		||||
    () => ({
 | 
			
		||||
      template: hbs`
 | 
			
		||||
        <h5 class="title is-5">Layout Loading</h5>
 | 
			
		||||
        <LayoutLoading/>
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
/* eslint-disable import/extensions */
 | 
			
		||||
import hbs from 'htmlbars-inline-precompile';
 | 
			
		||||
import { storiesOf } from '@storybook/ember';
 | 
			
		||||
import { withKnobs, select } from '@storybook/addon-knobs';
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
/* eslint-disable import/extensions */
 | 
			
		||||
import hbs from 'htmlbars-inline-precompile';
 | 
			
		||||
import { storiesOf } from '@storybook/ember';
 | 
			
		||||
import { withKnobs, text, boolean } from '@storybook/addon-knobs';
 | 
			
		||||
@@ -1,25 +1,27 @@
 | 
			
		||||
/* eslint-disable import/extensions */
 | 
			
		||||
import hbs from 'htmlbars-inline-precompile';
 | 
			
		||||
import { storiesOf } from '@storybook/ember';
 | 
			
		||||
import notes from './message-error.md';
 | 
			
		||||
import EmberObject from '@ember/object';
 | 
			
		||||
 | 
			
		||||
let model = Ember.Object.create({
 | 
			
		||||
let model = EmberObject.create({
 | 
			
		||||
  adapterError: {
 | 
			
		||||
    message: 'This is an adapterError on the model'
 | 
			
		||||
    message: 'This is an adapterError on the model',
 | 
			
		||||
  },
 | 
			
		||||
  isError: true
 | 
			
		||||
  isError: true,
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
storiesOf('MessageError/', module)
 | 
			
		||||
  .addParameters({ options: { showPanel: true } })
 | 
			
		||||
  .add(`MessageError`, () => ({
 | 
			
		||||
  .add(
 | 
			
		||||
    `MessageError`,
 | 
			
		||||
    () => ({
 | 
			
		||||
      template: hbs`
 | 
			
		||||
      <h5 class="title is-5">Message Error</h5>
 | 
			
		||||
      <MessageError @model={{model}} />
 | 
			
		||||
    `,
 | 
			
		||||
      context: {
 | 
			
		||||
      model
 | 
			
		||||
    }
 | 
			
		||||
        model,
 | 
			
		||||
      },
 | 
			
		||||
    }),
 | 
			
		||||
    { notes }
 | 
			
		||||
  );
 | 
			
		||||
@@ -1,12 +1,12 @@
 | 
			
		||||
/* eslint-disable import/extensions */
 | 
			
		||||
import hbs from 'htmlbars-inline-precompile';
 | 
			
		||||
import { storiesOf } from '@storybook/ember';
 | 
			
		||||
import notes from './popup-menu.md';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
storiesOf('PopupMenu/', module)
 | 
			
		||||
  .addParameters({ options: { showPanel: true } })
 | 
			
		||||
  .add(`PopupMenu`, () => ({
 | 
			
		||||
  .add(
 | 
			
		||||
    `PopupMenu`,
 | 
			
		||||
    () => ({
 | 
			
		||||
      template: hbs`
 | 
			
		||||
        <h5 class="title is-5">Popup Menu</h5>
 | 
			
		||||
        <PopupMenu>
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
/* eslint-disable import/extensions */
 | 
			
		||||
import hbs from 'htmlbars-inline-precompile';
 | 
			
		||||
import { storiesOf } from '@storybook/ember';
 | 
			
		||||
import { withKnobs, object, text, boolean, select } from '@storybook/addon-knobs';
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
/* eslint-disable import/extensions */
 | 
			
		||||
import hbs from 'htmlbars-inline-precompile';
 | 
			
		||||
import { storiesOf } from '@storybook/ember';
 | 
			
		||||
import notes from './toggle-button.md';
 | 
			
		||||
@@ -1,13 +1,14 @@
 | 
			
		||||
/* eslint-disable import/extensions */
 | 
			
		||||
import hbs from 'htmlbars-inline-precompile';
 | 
			
		||||
import { storiesOf } from '@storybook/ember';
 | 
			
		||||
import { withKnobs, select } from '@storybook/addon-knobs';
 | 
			
		||||
import { withKnobs } from '@storybook/addon-knobs';
 | 
			
		||||
import notes from './toolbar-actions.md';
 | 
			
		||||
 | 
			
		||||
storiesOf('Toolbar/', module)
 | 
			
		||||
  .addParameters({ options: { showPanel: true } })
 | 
			
		||||
  .addDecorator(withKnobs())
 | 
			
		||||
  .add(`ToolbarActions`, () => ({
 | 
			
		||||
  .add(
 | 
			
		||||
    `ToolbarActions`,
 | 
			
		||||
    () => ({
 | 
			
		||||
      template: hbs`
 | 
			
		||||
        <h5 class="title is-5">ToolbarActions</h5>
 | 
			
		||||
        <Toolbar>
 | 
			
		||||
@@ -1,14 +1,14 @@
 | 
			
		||||
/* eslint-disable import/extensions */
 | 
			
		||||
import hbs from 'htmlbars-inline-precompile';
 | 
			
		||||
import { storiesOf } from '@storybook/ember';
 | 
			
		||||
import { withKnobs, text } from '@storybook/addon-knobs';
 | 
			
		||||
import notes from './toolbar-download-button.md';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
storiesOf('Toolbar/', module)
 | 
			
		||||
  .addParameters({ options: { showPanel: true } })
 | 
			
		||||
  .addDecorator(withKnobs())
 | 
			
		||||
  .add(`ToolbarDownloadButton`,() => ({
 | 
			
		||||
  .add(
 | 
			
		||||
    `ToolbarDownloadButton`,
 | 
			
		||||
    () => ({
 | 
			
		||||
      template: hbs`
 | 
			
		||||
      <h5 class="title is-5">ToolbarLink</h5>
 | 
			
		||||
      <div style="width: 400px;">
 | 
			
		||||
@@ -1,13 +1,14 @@
 | 
			
		||||
/* eslint-disable import/extensions */
 | 
			
		||||
import hbs from 'htmlbars-inline-precompile';
 | 
			
		||||
import { storiesOf } from '@storybook/ember';
 | 
			
		||||
import { withKnobs, select } from '@storybook/addon-knobs';
 | 
			
		||||
import { withKnobs } from '@storybook/addon-knobs';
 | 
			
		||||
import notes from './toolbar-filters.md';
 | 
			
		||||
 | 
			
		||||
storiesOf('Toolbar/', module)
 | 
			
		||||
  .addParameters({ options: { showPanel: true } })
 | 
			
		||||
  .addDecorator(withKnobs())
 | 
			
		||||
  .add(`ToolbarFilters`, () => ({
 | 
			
		||||
  .add(
 | 
			
		||||
    `ToolbarFilters`,
 | 
			
		||||
    () => ({
 | 
			
		||||
      template: hbs`
 | 
			
		||||
        <h5 class="title is-5">ToolbarFilters</h5>
 | 
			
		||||
        <Toolbar>
 | 
			
		||||
@@ -1,14 +1,14 @@
 | 
			
		||||
/* eslint-disable import/extensions */
 | 
			
		||||
import hbs from 'htmlbars-inline-precompile';
 | 
			
		||||
import { storiesOf } from '@storybook/ember';
 | 
			
		||||
import { withKnobs, select, text } from '@storybook/addon-knobs';
 | 
			
		||||
import notes from './toolbar-link.md';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
storiesOf('Toolbar/', module)
 | 
			
		||||
  .addParameters({ options: { showPanel: true } })
 | 
			
		||||
  .addDecorator(withKnobs())
 | 
			
		||||
  .add(`ToolbarLink`,() => ({
 | 
			
		||||
  .add(
 | 
			
		||||
    `ToolbarLink`,
 | 
			
		||||
    () => ({
 | 
			
		||||
      template: hbs`
 | 
			
		||||
      <h5 class="title is-5">ToolbarLink</h5>
 | 
			
		||||
      <div style="width: 400px;">
 | 
			
		||||
@@ -1,14 +1,14 @@
 | 
			
		||||
/* eslint-disable import/extensions */
 | 
			
		||||
import hbs from 'htmlbars-inline-precompile';
 | 
			
		||||
import { storiesOf } from '@storybook/ember';
 | 
			
		||||
import { withKnobs, select, text } from '@storybook/addon-knobs';
 | 
			
		||||
import notes from './toolbar-secret-link.md';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
storiesOf('Toolbar/', module)
 | 
			
		||||
  .addParameters({ options: { showPanel: true } })
 | 
			
		||||
  .addDecorator(withKnobs())
 | 
			
		||||
  .add(`ToolbarSecretLink`,() => ({
 | 
			
		||||
  .add(
 | 
			
		||||
    `ToolbarSecretLink`,
 | 
			
		||||
    () => ({
 | 
			
		||||
      template: hbs`
 | 
			
		||||
      <h5 class="title is-5">ToolbarLink</h5>
 | 
			
		||||
      <div style="width: 400px;">
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
/* eslint-disable import/extensions */
 | 
			
		||||
import hbs from 'htmlbars-inline-precompile';
 | 
			
		||||
import { storiesOf } from '@storybook/ember';
 | 
			
		||||
import { withKnobs, select } from '@storybook/addon-knobs';
 | 
			
		||||
@@ -7,7 +6,9 @@ import notes from './toolbar.md';
 | 
			
		||||
storiesOf('Toolbar/', module)
 | 
			
		||||
  .addParameters({ options: { showPanel: true } })
 | 
			
		||||
  .addDecorator(withKnobs())
 | 
			
		||||
  .add(`Toolbar`, () => ({
 | 
			
		||||
  .add(
 | 
			
		||||
    `Toolbar`,
 | 
			
		||||
    () => ({
 | 
			
		||||
      template: hbs`
 | 
			
		||||
      <h5 class="title is-5">Toolbar</h5>
 | 
			
		||||
      <section class="box is-fullwidth is-shadowless">
 | 
			
		||||
@@ -1,12 +1,12 @@
 | 
			
		||||
/* eslint-disable import/extensions */
 | 
			
		||||
import hbs from 'htmlbars-inline-precompile';
 | 
			
		||||
import { storiesOf } from '@storybook/ember';
 | 
			
		||||
import notes from './ttl-picker.md';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
storiesOf('TtlPicker/', module)
 | 
			
		||||
  .addParameters({ options: { showPanel: false } })
 | 
			
		||||
  .add(`TtlPicker`, () => ({
 | 
			
		||||
  .add(
 | 
			
		||||
    `TtlPicker`,
 | 
			
		||||
    () => ({
 | 
			
		||||
      template: hbs`
 | 
			
		||||
      <h5 class="title is-5">Ttl Picker</h5>
 | 
			
		||||
      <TtlPicker />
 | 
			
		||||
@@ -1,12 +1,12 @@
 | 
			
		||||
/* eslint-disable import/extensions */
 | 
			
		||||
import hbs from 'htmlbars-inline-precompile';
 | 
			
		||||
import { storiesOf } from '@storybook/ember';
 | 
			
		||||
import notes from './vault-logo-spinner.md';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
storiesOf('Loading/VaultLogoSpinner/', module)
 | 
			
		||||
  .addParameters({ options: { showPanel: true } })
 | 
			
		||||
  .add(`VaultLogoSpinner`, () => ({
 | 
			
		||||
  .add(
 | 
			
		||||
    `VaultLogoSpinner`,
 | 
			
		||||
    () => ({
 | 
			
		||||
      template: hbs`
 | 
			
		||||
        <h5 class="title is-5">Vault Logo Spinner</h5>
 | 
			
		||||
        <VaultLogoSpinner/>
 | 
			
		||||
							
								
								
									
										130
									
								
								ui/package.json
									
									
									
									
									
								
							
							
						
						
									
										130
									
								
								ui/package.json
									
									
									
									
									
								
							@@ -10,25 +10,24 @@
 | 
			
		||||
  },
 | 
			
		||||
  "scripts": {
 | 
			
		||||
    "build": "ember build -prod",
 | 
			
		||||
    "build-dev": "ember build",
 | 
			
		||||
    "lint:hbs": "ember-template-lint .",
 | 
			
		||||
    "build:dev": "ember build",
 | 
			
		||||
    "lint:hbs": "ember-template-lint app/**/* lib/**/*",
 | 
			
		||||
    "lint:js": "eslint .",
 | 
			
		||||
    "fmt": "yarn run fmt-js && yarn run fmt-styles",
 | 
			
		||||
    "fmt-js": "prettier-eslint --single-quote --no-use-tabs --trailing-comma es5 --print-width=110 --write '{app,tests,config,lib}/**/*.js'",
 | 
			
		||||
    "fmt-styles": "prettier --write app/styles/**/*.*",
 | 
			
		||||
    "fmt:js": "prettier-eslint --single-quote --no-use-tabs --trailing-comma es5 --print-width=110 --write '{app,tests,config,lib}/**/*.js'",
 | 
			
		||||
    "fmt:styles": "prettier --write app/styles/**/*.*",
 | 
			
		||||
    "start": "export VAULT_ADDR=http://localhost:8200; ember server --proxy=$VAULT_ADDR",
 | 
			
		||||
    "start2": "ember server --proxy=http://localhost:8202 --port=4202",
 | 
			
		||||
    "test": "node scripts/start-vault.js & yarn run lint:js & ember test",
 | 
			
		||||
    "test:browserstack": "export CI=true; node scripts/start-vault.js & node scripts/run-browserstack-tests.js",
 | 
			
		||||
    "test-oss": "yarn run test -f='!enterprise'",
 | 
			
		||||
    "test-quick": "node scripts/start-vault.js & ember test",
 | 
			
		||||
    "test-quick-oss": "yarn run test-quick -f='!enterprise'",
 | 
			
		||||
    "build-storybook": "build-storybook -s ../pkg/web_ui",
 | 
			
		||||
    "test": "yarn lint:js && node scripts/start-vault.js",
 | 
			
		||||
    "test:oss": "yarn run test -f='!enterprise'",
 | 
			
		||||
    "test:browserstack": "export CI=true; node scripts/start-vault.js --browserstack",
 | 
			
		||||
    "test:quick": "node scripts/start-vault.js",
 | 
			
		||||
    "test:quick-oss": "yarn test-quick -f='!enterprise'",
 | 
			
		||||
    "build:storybook": "build-storybook -s ../pkg/web_ui",
 | 
			
		||||
    "storybook": "start-storybook -p 6006 -s ../pkg/web_ui",
 | 
			
		||||
    "gen-story-md": "node scripts/gen-story-md.js"
 | 
			
		||||
  },
 | 
			
		||||
  "lint-staged": {
 | 
			
		||||
    "linters": {
 | 
			
		||||
    "*.js": [
 | 
			
		||||
      "prettier-eslint --single-quote --no-use-tabs --trailing-comma es5 --print-width 110 --write",
 | 
			
		||||
      "git add"
 | 
			
		||||
@@ -37,21 +36,21 @@
 | 
			
		||||
      "prettier --write",
 | 
			
		||||
      "git add"
 | 
			
		||||
    ]
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "@babel/plugin-proposal-object-rest-spread": "^7.5.5",
 | 
			
		||||
    "@ember/optional-features": "^0.7.0",
 | 
			
		||||
    "@hashicorp/structure-icons": "^1.3.0",
 | 
			
		||||
    "@storybook/ember-cli-storybook": "meirish/ember-cli-storybook#6bd58326d8c21e986d390b541ae5e49089d61b93",
 | 
			
		||||
    "Duration.js": "icholy/Duration.js#golang_compatible",
 | 
			
		||||
    "autosize": "^4.0.0",
 | 
			
		||||
    "babel-eslint": "^10.0.2",
 | 
			
		||||
    "babel-plugin-transform-object-rest-spread": "^6.23.0",
 | 
			
		||||
    "base64-js": "1.2.1",
 | 
			
		||||
    "broccoli-asset-rev": "^2.7.0",
 | 
			
		||||
    "base64-js": "^1.3.1",
 | 
			
		||||
    "broccoli-asset-rev": "^3.0.0",
 | 
			
		||||
    "broccoli-sri-hash": "meirish/broccoli-sri-hash#rooturl",
 | 
			
		||||
    "bulma": "^0.5.2",
 | 
			
		||||
    "bulma-switch": "^0.0.1",
 | 
			
		||||
    "codemirror": "5.15.2",
 | 
			
		||||
    "codemirror": "^5.48.2",
 | 
			
		||||
    "columnify": "^1.5.4",
 | 
			
		||||
    "cool-checkboxes-for-bulma.io": "^1.1.0",
 | 
			
		||||
    "d3-axis": "^1.0.8",
 | 
			
		||||
@@ -61,72 +60,71 @@
 | 
			
		||||
    "d3-time-format": "^2.1.1",
 | 
			
		||||
    "d3-tip": "^0.9.1",
 | 
			
		||||
    "d3-transition": "^1.2.0",
 | 
			
		||||
    "date-fns": "^1.29.0",
 | 
			
		||||
    "deepmerge": "^2.1.1",
 | 
			
		||||
    "date-fns": "^1.30.0",
 | 
			
		||||
    "deepmerge": "^4.0.0",
 | 
			
		||||
    "doctoc": "^1.4.0",
 | 
			
		||||
    "ember-api-actions": "^0.1.8",
 | 
			
		||||
    "ember-auto-import": "^1.2.3",
 | 
			
		||||
    "ember-api-actions": "^0.2.8",
 | 
			
		||||
    "ember-auto-import": "^1.5.2",
 | 
			
		||||
    "ember-basic-dropdown": "^1.0.0",
 | 
			
		||||
    "ember-basic-dropdown-hover": "^0.5.0",
 | 
			
		||||
    "ember-cli": "~3.5.1",
 | 
			
		||||
    "ember-basic-dropdown-hover": "^0.6.0",
 | 
			
		||||
    "ember-cli": "~3.11.0",
 | 
			
		||||
    "ember-cli-autoprefixer": "^0.8.1",
 | 
			
		||||
    "ember-cli-babel": "^6.16.0",
 | 
			
		||||
    "ember-cli-babel": "^7.8.0",
 | 
			
		||||
    "ember-cli-browserstack": "^0.0.7",
 | 
			
		||||
    "ember-cli-clipboard": "^0.8.0",
 | 
			
		||||
    "ember-cli-clipboard": "^0.13.0",
 | 
			
		||||
    "ember-cli-content-security-policy": "^1.0.0",
 | 
			
		||||
    "ember-cli-dependency-checker": "^3.0.0",
 | 
			
		||||
    "ember-cli-deprecation-workflow": "^1.0.1",
 | 
			
		||||
    "ember-cli-element-closest-polyfill": "^0.0.1",
 | 
			
		||||
    "ember-cli-flash": "1.7.1",
 | 
			
		||||
    "ember-cli-flash": "^1.7.2",
 | 
			
		||||
    "ember-cli-htmlbars": "^3.0.0",
 | 
			
		||||
    "ember-cli-htmlbars-inline-precompile": "^1.0.3",
 | 
			
		||||
    "ember-cli-inject-live-reload": "^1.8.2",
 | 
			
		||||
    "ember-cli-htmlbars-inline-precompile": "^2.1.0",
 | 
			
		||||
    "ember-cli-inject-live-reload": "^2.0.1",
 | 
			
		||||
    "ember-cli-page-object": "^1.15.3",
 | 
			
		||||
    "ember-cli-pretender": "^3.1.1",
 | 
			
		||||
    "ember-cli-sass": "^9.0.0",
 | 
			
		||||
    "ember-cli-sass": "^10.0.1",
 | 
			
		||||
    "ember-cli-sri": "meirish/ember-cli-sri#rooturl",
 | 
			
		||||
    "ember-cli-string-helpers": "^1.5.0",
 | 
			
		||||
    "ember-cli-template-lint": "^1.0.0-beta.1",
 | 
			
		||||
    "ember-cli-uglify": "^2.1.0",
 | 
			
		||||
    "ember-composable-helpers": "^2.0.3",
 | 
			
		||||
    "ember-computed-query": "^0.1.1",
 | 
			
		||||
    "ember-concurrency": "^0.10.0",
 | 
			
		||||
    "ember-cli-string-helpers": "^4.0.0",
 | 
			
		||||
    "ember-cli-template-lint": "^1.0.0-beta.3",
 | 
			
		||||
    "ember-cli-uglify": "^3.0.0",
 | 
			
		||||
    "ember-composable-helpers": "^2.3.1",
 | 
			
		||||
    "ember-concurrency": "^1.0.0",
 | 
			
		||||
    "ember-concurrency-test-waiter": "^0.3.1",
 | 
			
		||||
    "ember-copy": "^1.0.0",
 | 
			
		||||
    "ember-data": "~3.4.0",
 | 
			
		||||
    "ember-data-model-fragments": "^3.3.0",
 | 
			
		||||
    "ember-data": "~3.8.0",
 | 
			
		||||
    "ember-data-model-fragments": "^4.0.0",
 | 
			
		||||
    "ember-engines": "^0.8.0",
 | 
			
		||||
    "ember-export-application-global": "^2.0.0",
 | 
			
		||||
    "ember-fetch": "^6.5.1",
 | 
			
		||||
    "ember-inflector": "^3.0.0",
 | 
			
		||||
    "ember-link-action": "^0.1.2",
 | 
			
		||||
    "ember-load-initializers": "^1.1.0",
 | 
			
		||||
    "ember-link-action": "^1.0.0",
 | 
			
		||||
    "ember-load-initializers": "^2.0.0",
 | 
			
		||||
    "ember-maybe-import-regenerator": "^0.1.6",
 | 
			
		||||
    "ember-maybe-in-element": "^0.1.3",
 | 
			
		||||
    "ember-maybe-in-element": "^0.4.0",
 | 
			
		||||
    "ember-power-select-with-create": "cibernox/ember-power-select-with-create#6203918f247c1c5d692db4f9185ab8321d2125e1",
 | 
			
		||||
    "ember-qunit": "^4.4.1",
 | 
			
		||||
    "ember-radio-button": "^1.1.1",
 | 
			
		||||
    "ember-radio-button": "^2.0.1",
 | 
			
		||||
    "ember-resolver": "^5.0.1",
 | 
			
		||||
    "ember-responsive": "^3.0.0-beta.3",
 | 
			
		||||
    "ember-router-helpers": "^0.2.0",
 | 
			
		||||
    "ember-sinon": "^1.0.1",
 | 
			
		||||
    "ember-source": "~3.4.0",
 | 
			
		||||
    "ember-svg-jar": "^1.2.2",
 | 
			
		||||
    "ember-sinon": "^4.0.0",
 | 
			
		||||
    "ember-source": "~3.8.0",
 | 
			
		||||
    "ember-svg-jar": "^2.1.0",
 | 
			
		||||
    "ember-test-selectors": "^2.1.0",
 | 
			
		||||
    "ember-truth-helpers": "^2.1.0",
 | 
			
		||||
    "escape-string-regexp": "^1.0.5",
 | 
			
		||||
    "eslint": "^5.16.0",
 | 
			
		||||
    "eslint-config-prettier": "^3.1.0",
 | 
			
		||||
    "eslint-plugin-ember": "^6.3.0",
 | 
			
		||||
    "eslint-plugin-prettier": "^3.0.0",
 | 
			
		||||
    "escape-string-regexp": "^2.0.0",
 | 
			
		||||
    "eslint": "^6.1.0",
 | 
			
		||||
    "eslint-config-prettier": "^6.0.0",
 | 
			
		||||
    "eslint-plugin-ember": "^6.7.0",
 | 
			
		||||
    "eslint-plugin-prettier": "^3.1.0",
 | 
			
		||||
    "flat": "^4.1.0",
 | 
			
		||||
    "ivy-codemirror": "2.1.0",
 | 
			
		||||
    "jsonlint": "1.6.0",
 | 
			
		||||
    "ivy-codemirror": "IvyApp/ivy-codemirror#fb09333c5144da47e14a9e6260f80577d5408374",
 | 
			
		||||
    "jsonlint": "^1.6.3",
 | 
			
		||||
    "loader.js": "^4.7.0",
 | 
			
		||||
    "node-sass": "^4.10.0",
 | 
			
		||||
    "normalize.css": "4.1.1",
 | 
			
		||||
    "prettier": "^1.14.3",
 | 
			
		||||
    "prettier-eslint-cli": "^4.7.1",
 | 
			
		||||
    "prettier-eslint-cli": "^5.0.0",
 | 
			
		||||
    "qunit-dom": "^0.7.1",
 | 
			
		||||
    "route-recognizer": "^0.3.4",
 | 
			
		||||
    "sass-svg-uri": "^1.0.0",
 | 
			
		||||
@@ -134,29 +132,29 @@
 | 
			
		||||
    "string.prototype.endswith": "^0.2.0",
 | 
			
		||||
    "string.prototype.startswith": "^0.2.0",
 | 
			
		||||
    "swagger-ui-dist": "^3.22.3",
 | 
			
		||||
    "text-encoder-lite": "1.0.0",
 | 
			
		||||
    "walk-sync": "^0.3.3",
 | 
			
		||||
    "text-encoder-lite": "2.0.0",
 | 
			
		||||
    "walk-sync": "^2.0.2",
 | 
			
		||||
    "xstate": "^3.3.3",
 | 
			
		||||
    "yargs-parser": "^13.0.0"
 | 
			
		||||
    "yargs-parser": "^13.1.1"
 | 
			
		||||
  },
 | 
			
		||||
  "optionalDependencies": {
 | 
			
		||||
    "@babel/core": "^7.3.4",
 | 
			
		||||
    "@storybook/addon-knobs": "^5.0.5",
 | 
			
		||||
    "@storybook/addon-links": "^5.0.5",
 | 
			
		||||
    "@storybook/addon-notes": "^5.0.5",
 | 
			
		||||
    "@storybook/addon-viewport": "^5.0.5",
 | 
			
		||||
    "@storybook/addons": "^5.0.5",
 | 
			
		||||
    "@storybook/ember": "^5.0.5",
 | 
			
		||||
    "@storybook/ember-cli-storybook": "meirish/ember-cli-storybook#6bd58326d8c21e986d390b541ae5e49089d61b93",
 | 
			
		||||
    "babel-loader": "^8.0.5",
 | 
			
		||||
    "jsdoc-to-markdown": "^4.0.1",
 | 
			
		||||
    "lint-staged": "^8.0.4"
 | 
			
		||||
    "@babel/core": "^7.5.5",
 | 
			
		||||
    "@storybook/addon-knobs": "^5.1.10",
 | 
			
		||||
    "@storybook/addon-links": "^5.1.10",
 | 
			
		||||
    "@storybook/addon-notes": "^5.1.10",
 | 
			
		||||
    "@storybook/addon-viewport": "^5.1.10",
 | 
			
		||||
    "@storybook/addons": "^5.1.10",
 | 
			
		||||
    "@storybook/ember": "^5.1.10",
 | 
			
		||||
    "babel-loader": "^8.0.6",
 | 
			
		||||
    "jsdoc-to-markdown": "^5.0.0",
 | 
			
		||||
    "lint-staged": "^9.2.1"
 | 
			
		||||
  },
 | 
			
		||||
  "resolutions": {
 | 
			
		||||
    "handlebars": "^4.1.2"
 | 
			
		||||
  },
 | 
			
		||||
  "engines": {
 | 
			
		||||
    "node": " >= 10.*"
 | 
			
		||||
    "node": " >= 10.* <11",
 | 
			
		||||
    "yarn": "1.17.3"
 | 
			
		||||
  },
 | 
			
		||||
  "private": true,
 | 
			
		||||
  "ember-addon": {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,37 +0,0 @@
 | 
			
		||||
#!/usr/bin/env node
 | 
			
		||||
/* eslint-env node */
 | 
			
		||||
/* eslint-disable no-console */
 | 
			
		||||
 | 
			
		||||
const execa = require('execa');
 | 
			
		||||
const chalk = require('chalk');
 | 
			
		||||
 | 
			
		||||
function run(command, args = []) {
 | 
			
		||||
  console.log(chalk.dim('$ ' + command + ' ' + args.join(' ')));
 | 
			
		||||
 | 
			
		||||
  let p = execa(command, args);
 | 
			
		||||
  p.stdout.pipe(process.stdout);
 | 
			
		||||
  p.stderr.pipe(process.stderr);
 | 
			
		||||
 | 
			
		||||
  return p;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
(async function() {
 | 
			
		||||
  try {
 | 
			
		||||
    await run('ember', ['browserstack:connect']);
 | 
			
		||||
    try {
 | 
			
		||||
      await run('ember', ['test', '-f=secrets/secret/create', '-c', 'testem.browserstack.js']);
 | 
			
		||||
 | 
			
		||||
      console.log('success');
 | 
			
		||||
      process.exit(0);
 | 
			
		||||
    } finally {
 | 
			
		||||
      if (process.env.CI === 'true') {
 | 
			
		||||
        await run('ember', ['browserstack:results']);
 | 
			
		||||
      }
 | 
			
		||||
      await run('ember', ['browserstack:disconnect']);
 | 
			
		||||
    }
 | 
			
		||||
  } catch (error) {
 | 
			
		||||
    console.log('error');
 | 
			
		||||
    console.log(error);
 | 
			
		||||
    process.exit(1);
 | 
			
		||||
  }
 | 
			
		||||
})();
 | 
			
		||||
@@ -1,36 +1,60 @@
 | 
			
		||||
#!/usr/bin/env node
 | 
			
		||||
/* eslint-disable */
 | 
			
		||||
/* eslint-env node */
 | 
			
		||||
/* eslint-disable no-console */
 | 
			
		||||
 | 
			
		||||
if (process.argv[2]) {
 | 
			
		||||
  process.kill(process.argv[2], 'SIGINT');
 | 
			
		||||
  process.exit(0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
process.env.TERM = 'dumb';
 | 
			
		||||
var fs = require('fs');
 | 
			
		||||
var path = require('path');
 | 
			
		||||
var readline = require('readline');
 | 
			
		||||
var spawn = require('child_process').spawn;
 | 
			
		||||
var vault = spawn('vault', [
 | 
			
		||||
var execa = require('execa');
 | 
			
		||||
var chalk = require('chalk');
 | 
			
		||||
 | 
			
		||||
function run(command, args = [], shareStd = true) {
 | 
			
		||||
  console.log(chalk.dim('$ ' + command + ' ' + args.join(' ')));
 | 
			
		||||
  // cleanup means that execa will handle stopping the vault subprocess
 | 
			
		||||
  // inherit all of the stdin/out/err so that testem still works as if you were running it directly
 | 
			
		||||
  if (shareStd) {
 | 
			
		||||
    return execa(command, args, { cleanup: true, stdin: 'inherit', stdout: 'inherit', stderr: 'inherit' });
 | 
			
		||||
  }
 | 
			
		||||
  let p = execa(command, args, { cleanup: true });
 | 
			
		||||
  p.stdout.pipe(process.stdout);
 | 
			
		||||
  p.stderr.pipe(process.stderr);
 | 
			
		||||
  return p;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var output = '';
 | 
			
		||||
var unseal, root, written;
 | 
			
		||||
 | 
			
		||||
async function processLines(input, eachLine = () => {}) {
 | 
			
		||||
  const rl = readline.createInterface({
 | 
			
		||||
    input,
 | 
			
		||||
    terminal: true,
 | 
			
		||||
  });
 | 
			
		||||
  for await (const line of rl) {
 | 
			
		||||
    eachLine(line);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
(async function() {
 | 
			
		||||
  try {
 | 
			
		||||
    let vault = run(
 | 
			
		||||
      'vault',
 | 
			
		||||
      [
 | 
			
		||||
        'server',
 | 
			
		||||
        '-dev',
 | 
			
		||||
        '-dev-ha',
 | 
			
		||||
        '-dev-transactional',
 | 
			
		||||
        '-dev-root-token-id=root',
 | 
			
		||||
        '-dev-listen-address=127.0.0.1:9200',
 | 
			
		||||
]);
 | 
			
		||||
      ],
 | 
			
		||||
      false
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
var output = '';
 | 
			
		||||
var unseal, root;
 | 
			
		||||
 | 
			
		||||
readline
 | 
			
		||||
  .createInterface({
 | 
			
		||||
    input: vault.stdout,
 | 
			
		||||
    terminal: false,
 | 
			
		||||
  })
 | 
			
		||||
  .on('line', function(line) {
 | 
			
		||||
    processLines(vault.stdout, function(line) {
 | 
			
		||||
      if (written) {
 | 
			
		||||
        output = null;
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
      output = output + line;
 | 
			
		||||
    console.log(line);
 | 
			
		||||
      var unsealMatch = output.match(/Unseal Key: (.+)$/m);
 | 
			
		||||
      if (unsealMatch && !unseal) {
 | 
			
		||||
        unseal = unsealMatch[1];
 | 
			
		||||
@@ -39,7 +63,7 @@ readline
 | 
			
		||||
      if (rootMatch && !root) {
 | 
			
		||||
        root = rootMatch[1];
 | 
			
		||||
      }
 | 
			
		||||
    if (root && unseal) {
 | 
			
		||||
      if (root && unseal && !written) {
 | 
			
		||||
        fs.writeFile(
 | 
			
		||||
          path.join(process.cwd(), 'tests/helpers/vault-keys.js'),
 | 
			
		||||
          `export default ${JSON.stringify({ unseal, root }, null, 2)}`,
 | 
			
		||||
@@ -47,34 +71,34 @@ readline
 | 
			
		||||
            if (err) throw err;
 | 
			
		||||
          }
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        written = true;
 | 
			
		||||
        console.log('VAULT SERVER READY');
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
    try {
 | 
			
		||||
      if (process.argv[2] === '--browserstack') {
 | 
			
		||||
        await run('ember', ['browserstack:connect']);
 | 
			
		||||
        try {
 | 
			
		||||
          await run('ember', ['test', '-f=secrets/secret/create', '-c', 'testem.browserstack.js']);
 | 
			
		||||
 | 
			
		||||
vault.stderr.on('data', function(data) {
 | 
			
		||||
  console.log(data.toString());
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
vault.on('close', function(code) {
 | 
			
		||||
  console.log(`child process exited with code ${code}`);
 | 
			
		||||
  process.exit();
 | 
			
		||||
});
 | 
			
		||||
vault.on('error', function(error) {
 | 
			
		||||
  console.log(`child process errored: ${error}`);
 | 
			
		||||
  process.exit();
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var pidFile = 'vault-ui-integration-server.pid';
 | 
			
		||||
process.on('SIGINT', function() {
 | 
			
		||||
  vault.kill('SIGINT');
 | 
			
		||||
  process.exit();
 | 
			
		||||
});
 | 
			
		||||
process.on('exit', function() {
 | 
			
		||||
  vault.kill('SIGINT');
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
fs.writeFile(pidFile, process.pid, err => {
 | 
			
		||||
  if (err) throw err;
 | 
			
		||||
  console.log('The file has been saved!');
 | 
			
		||||
});
 | 
			
		||||
          console.log('success');
 | 
			
		||||
          process.exit(0);
 | 
			
		||||
        } finally {
 | 
			
		||||
          if (process.env.CI === 'true') {
 | 
			
		||||
            await run('ember', ['browserstack:results']);
 | 
			
		||||
          }
 | 
			
		||||
          await run('ember', ['browserstack:disconnect']);
 | 
			
		||||
        }
 | 
			
		||||
      } else {
 | 
			
		||||
        await run('ember', ['test', ...process.argv.slice(2)]);
 | 
			
		||||
      }
 | 
			
		||||
    } catch (error) {
 | 
			
		||||
      console.log(error);
 | 
			
		||||
    } finally {
 | 
			
		||||
      process.exit(0);
 | 
			
		||||
    }
 | 
			
		||||
  } catch (error) {
 | 
			
		||||
    console.log(error);
 | 
			
		||||
    process.exit(0);
 | 
			
		||||
  }
 | 
			
		||||
})();
 | 
			
		||||
 
 | 
			
		||||
@@ -1,35 +0,0 @@
 | 
			
		||||
/* eslint-disable import/extensions */
 | 
			
		||||
import hbs from 'htmlbars-inline-precompile';
 | 
			
		||||
import { storiesOf } from '@storybook/ember';
 | 
			
		||||
import { withKnobs, text } from '@storybook/addon-knobs';
 | 
			
		||||
import notes from './empty-state.md';
 | 
			
		||||
 | 
			
		||||
storiesOf('EmptyState/', module)
 | 
			
		||||
  .addParameters({ options: { showPanel: true } })
 | 
			
		||||
  .addDecorator(withKnobs({escapeHTML: false}))
 | 
			
		||||
  .add(`EmptyState`, () => ({
 | 
			
		||||
    template: hbs`
 | 
			
		||||
      <h5 class="title is-5">Empty State</h5>
 | 
			
		||||
      <EmptyState @title={{title}} @message={{message}} />
 | 
			
		||||
    `,
 | 
			
		||||
    context: {
 | 
			
		||||
      title: text('Title', 'You don\'t have an secrets yet'),
 | 
			
		||||
      message: text('Message', 'An explanation of why you don\'t have any secrets but also you maybe want to create one.')
 | 
			
		||||
    },
 | 
			
		||||
  }),
 | 
			
		||||
  {notes}
 | 
			
		||||
  )
 | 
			
		||||
  .add(`EmptyState with content block`, () => ({
 | 
			
		||||
    template: hbs`
 | 
			
		||||
      <h5 class="title is-5">Empty State</h5>
 | 
			
		||||
      <EmptyState @title={{title}} @message={{message}}>
 | 
			
		||||
        <DocLink @path="/docs/secrets/kv/kv-v2.html">Learn about KV v2</DocLink>
 | 
			
		||||
      </EmptyState>
 | 
			
		||||
    `,
 | 
			
		||||
    context: {
 | 
			
		||||
      title: text('Title', 'You don\'t have an secrets yet'),
 | 
			
		||||
      message: text('Message', 'An explanation of why you don\'t have any secrets but also you maybe want to create one.')
 | 
			
		||||
    },
 | 
			
		||||
  }),
 | 
			
		||||
  {notes}
 | 
			
		||||
  );
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
/* eslint-disable import/extensions */
 | 
			
		||||
import hbs from 'htmlbars-inline-precompile';
 | 
			
		||||
import { storiesOf } from '@storybook/ember';
 | 
			
		||||
import notes from './search-select.md';
 | 
			
		||||
 
 | 
			
		||||
@@ -18,9 +18,6 @@ const config = {
 | 
			
		||||
      ].filter(Boolean),
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
  on_exit:
 | 
			
		||||
    '[ -e ../../vault-ui-integration-server.pid ] && node ../../scripts/start-vault.js `cat ../../vault-ui-integration-server.pid`; [ -e ../../vault-ui-integration-server.pid ] && rm ../../vault-ui-integration-server.pid',
 | 
			
		||||
 | 
			
		||||
  proxies: {
 | 
			
		||||
    '/v1': {
 | 
			
		||||
      target: 'http://localhost:9200',
 | 
			
		||||
 
 | 
			
		||||
@@ -171,10 +171,8 @@ module('Acceptance | Enterprise | KMIP secrets', function(hooks) {
 | 
			
		||||
      `/vault/secrets/${path}/kmip/scopes/${scope}/roles/${role}`,
 | 
			
		||||
      'cancel navigates to role show'
 | 
			
		||||
    );
 | 
			
		||||
    await rolesPage
 | 
			
		||||
      .detailDelete()
 | 
			
		||||
      .delete()
 | 
			
		||||
      .confirmDelete();
 | 
			
		||||
    await rolesPage.delete().confirmDelete();
 | 
			
		||||
 | 
			
		||||
    assert.equal(
 | 
			
		||||
      currentURL(),
 | 
			
		||||
      `/vault/secrets/${path}/kmip/scopes/${scope}/roles`,
 | 
			
		||||
@@ -209,8 +207,7 @@ module('Acceptance | Enterprise | KMIP secrets', function(hooks) {
 | 
			
		||||
    await credentialsPage.visit({ backend: path, scope, role });
 | 
			
		||||
    // revoke the credentials
 | 
			
		||||
    await credentialsPage.listItemLinks.objectAt(0).menuToggle();
 | 
			
		||||
    await credentialsPage.delete();
 | 
			
		||||
    await credentialsPage.confirmDelete();
 | 
			
		||||
    await credentialsPage.delete().confirmDelete();
 | 
			
		||||
    assert.equal(credentialsPage.listItemLinks.length, 0, 'renders no credentials');
 | 
			
		||||
    assert.ok(credentialsPage.isEmpty, 'renders empty');
 | 
			
		||||
  });
 | 
			
		||||
@@ -218,10 +215,7 @@ module('Acceptance | Enterprise | KMIP secrets', function(hooks) {
 | 
			
		||||
  test('it can revoke from the credentials show page', async function(assert) {
 | 
			
		||||
    let { path, scope, role, serial } = await generateCreds();
 | 
			
		||||
    await credentialsPage.visitDetail({ backend: path, scope, role, serial });
 | 
			
		||||
    await credentialsPage
 | 
			
		||||
      .detailRevoke()
 | 
			
		||||
      .delete()
 | 
			
		||||
      .confirmDelete();
 | 
			
		||||
    await credentialsPage.delete().confirmDelete();
 | 
			
		||||
 | 
			
		||||
    assert.equal(
 | 
			
		||||
      currentURL(),
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
import { click, currentRouteName, currentURL, visit } from '@ember/test-helpers';
 | 
			
		||||
import { click } from '@ember/test-helpers';
 | 
			
		||||
import { module, test } from 'qunit';
 | 
			
		||||
import { setupApplicationTest } from 'ember-qunit';
 | 
			
		||||
import { create } from 'ember-cli-page-object';
 | 
			
		||||
 
 | 
			
		||||
@@ -25,7 +25,6 @@ module('Acceptance | secrets/secret/create', function(hooks) {
 | 
			
		||||
 | 
			
		||||
  hooks.beforeEach(async function() {
 | 
			
		||||
    this.server = apiStub({ usePassthrough: true });
 | 
			
		||||
    await logout.visit();
 | 
			
		||||
    return authPage.login();
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
@@ -215,7 +214,6 @@ module('Acceptance | secrets/secret/create', function(hooks) {
 | 
			
		||||
    await writeSecret(backend, 'secret', 'foo', 'bar');
 | 
			
		||||
    assert.equal(currentRouteName(), 'vault.cluster.secrets.backend.show', 'redirects to the show page');
 | 
			
		||||
    assert.ok(showPage.editIsPresent, 'shows the edit button');
 | 
			
		||||
    await logout.visit();
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  test('version 2 with restricted policy still allows edit', async function(assert) {
 | 
			
		||||
@@ -247,7 +245,6 @@ module('Acceptance | secrets/secret/create', function(hooks) {
 | 
			
		||||
 | 
			
		||||
    assert.equal(currentRouteName(), 'vault.cluster.secrets.backend.show', 'redirects to the show page');
 | 
			
		||||
    assert.ok(showPage.editIsPresent, 'shows the edit button');
 | 
			
		||||
    await logout.visit();
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  test('paths are properly encoded', async function(assert) {
 | 
			
		||||
@@ -389,7 +386,6 @@ module('Acceptance | secrets/secret/create', function(hooks) {
 | 
			
		||||
 | 
			
		||||
    await editPage.editSecret('bar', 'baz');
 | 
			
		||||
    assert.equal(currentRouteName(), 'vault.cluster.secrets.backend.show', 'redirects to the show page');
 | 
			
		||||
    await logout.visit();
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  test('write without read: version 2 with metadata read', async function(assert) {
 | 
			
		||||
@@ -409,7 +405,6 @@ module('Acceptance | secrets/secret/create', function(hooks) {
 | 
			
		||||
 | 
			
		||||
    await editPage.editSecret('bar', 'baz');
 | 
			
		||||
    assert.equal(currentRouteName(), 'vault.cluster.secrets.backend.show', 'redirects to the show page');
 | 
			
		||||
    await logout.visit();
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  test('write without read: version 1', async function(assert) {
 | 
			
		||||
@@ -428,6 +423,5 @@ module('Acceptance | secrets/secret/create', function(hooks) {
 | 
			
		||||
 | 
			
		||||
    await editPage.editSecret('bar', 'baz');
 | 
			
		||||
    assert.equal(currentRouteName(), 'vault.cluster.secrets.backend.show', 'redirects to the show page');
 | 
			
		||||
    await logout.visit();
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -248,7 +248,7 @@ module('Acceptance | transit', function(hooks) {
 | 
			
		||||
      // wait for capabilities
 | 
			
		||||
      await settled();
 | 
			
		||||
      assert.dom('[data-test-transit-key-version-row]').exists({ count: 1 }, `${name}: only one key version`);
 | 
			
		||||
      await click('[data-test-confirm-action-trigger');
 | 
			
		||||
      await click('[data-test-confirm-action-trigger]');
 | 
			
		||||
      await click('[data-test-confirm-button]');
 | 
			
		||||
      // wait for rotate call
 | 
			
		||||
      await settled();
 | 
			
		||||
 
 | 
			
		||||
@@ -14,12 +14,14 @@ import form from '../../pages/components/auth-jwt';
 | 
			
		||||
import { ERROR_WINDOW_CLOSED, ERROR_MISSING_PARAMS } from 'vault/components/auth-jwt';
 | 
			
		||||
 | 
			
		||||
const component = create(form);
 | 
			
		||||
const windows = [];
 | 
			
		||||
const fakeWindow = EmberObject.extend(Evented, {
 | 
			
		||||
  init() {
 | 
			
		||||
    this._super(...arguments);
 | 
			
		||||
    this.__proto__.on('close', () => {
 | 
			
		||||
    this.on('close', () => {
 | 
			
		||||
      this.set('closed', true);
 | 
			
		||||
    });
 | 
			
		||||
    windows.push(this);
 | 
			
		||||
  },
 | 
			
		||||
  screen: computed(function() {
 | 
			
		||||
    return {
 | 
			
		||||
@@ -41,7 +43,7 @@ fakeWindow.reopen({
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  close() {
 | 
			
		||||
    fakeWindow.proto().trigger('close');
 | 
			
		||||
    windows.forEach(w => w.trigger('close'));
 | 
			
		||||
  },
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -71,14 +71,14 @@ module('Integration | Component | edit form kmip role', function(hooks) {
 | 
			
		||||
    this.set('model', model);
 | 
			
		||||
    await render(hbs`<EditFormKmipRole @model={{model}} />`);
 | 
			
		||||
 | 
			
		||||
    assert.dom('[data-test-input="operationAll"').isChecked('sets operationAll');
 | 
			
		||||
    assert.dom('[data-test-input="operationAll"]').isChecked('sets operationAll');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  test('it renders: operationAll', async function(assert) {
 | 
			
		||||
    let model = createModel({ operationAll: true });
 | 
			
		||||
    this.set('model', model);
 | 
			
		||||
    await render(hbs`<EditFormKmipRole @model={{model}} />`);
 | 
			
		||||
    assert.dom('[data-test-input="operationAll"').isChecked('sets operationAll');
 | 
			
		||||
    assert.dom('[data-test-input="operationAll"]').isChecked('sets operationAll');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  test('it renders: operationNone', async function(assert) {
 | 
			
		||||
@@ -95,7 +95,7 @@ module('Integration | Component | edit form kmip role', function(hooks) {
 | 
			
		||||
    await render(hbs`<EditFormKmipRole @model={{model}} />`);
 | 
			
		||||
 | 
			
		||||
    assert.dom('[data-test-input="operationNone"]').isChecked('sets operationNone');
 | 
			
		||||
    assert.dom('[data-test-input="operationAll"').isNotChecked('sets operationAll');
 | 
			
		||||
    assert.dom('[data-test-input="operationAll"]').isNotChecked('sets operationAll');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  let savingTests = [
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@ module('Integration | Component | toolbar-link', function(hooks) {
 | 
			
		||||
  setupRenderingTest(hooks);
 | 
			
		||||
 | 
			
		||||
  test('it renders', async function(assert) {
 | 
			
		||||
    await render(hbs`<ToolbarLink @params="/secrets">Link</ToolbarLink>`);
 | 
			
		||||
    await render(hbs`<ToolbarLink @params={{array '/secrets'}}>Link</ToolbarLink>`);
 | 
			
		||||
 | 
			
		||||
    assert.equal(this.element.textContent.trim(), 'Link');
 | 
			
		||||
    assert.ok(isPresent('.toolbar-link'));
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
import { run } from '@ember/runloop';
 | 
			
		||||
import { copy } from '@ember/object/internals';
 | 
			
		||||
import { copy } from 'ember-copy';
 | 
			
		||||
import { module, test } from 'qunit';
 | 
			
		||||
import { setupTest } from 'ember-qunit';
 | 
			
		||||
import { TOKEN_SEPARATOR, TOKEN_PREFIX, ROOT_PREFIX } from 'vault/services/auth';
 | 
			
		||||
 
 | 
			
		||||
@@ -2,9 +2,12 @@ import { create, visitable, fillable, clickable } from 'ember-cli-page-object';
 | 
			
		||||
 | 
			
		||||
export default create({
 | 
			
		||||
  visit: visitable('/vault/auth'),
 | 
			
		||||
  logout: visitable('/vault/logout'),
 | 
			
		||||
  submit: clickable('[data-test-auth-submit]'),
 | 
			
		||||
  tokenInput: fillable('[data-test-token]'),
 | 
			
		||||
  login: async function(token) {
 | 
			
		||||
    // make sure we're always logged out and logged back in :w
 | 
			
		||||
    await this.logout();
 | 
			
		||||
    await this.visit({ with: 'token' });
 | 
			
		||||
    if (token) {
 | 
			
		||||
      return this.tokenInput(token).submit();
 | 
			
		||||
 
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user