diff --git a/Makefile b/Makefile index f49aa2034f..fe53eefcde 100644 --- a/Makefile +++ b/Makefile @@ -121,7 +121,15 @@ ember-dist: @cd ui && yarn run build @rm -rf ui/if-you-need-to-delete-this-open-an-issue-async-disk-cache +ember-dist-dev: + @echo "--> Installing JavaScript assets" + @cd ui && yarn + @cd ui && npm rebuild node-sass + @echo "--> Building Ember application" + @cd ui && yarn run build-dev + static-dist: ember-dist static-assets +static-dist-dev: ember-dist-dev static-assets proto: protoc vault/*.proto --go_out=plugins=grpc:../../.. @@ -166,4 +174,4 @@ hana-database-plugin: mongodb-database-plugin: @CGO_ENABLED=0 go build -o bin/mongodb-database-plugin ./plugins/database/mongodb/mongodb-database-plugin -.PHONY: bin default prep test vet bootstrap fmt fmtcheck mysql-database-plugin mysql-legacy-database-plugin cassandra-database-plugin postgresql-database-plugin mssql-database-plugin hana-database-plugin mongodb-database-plugin static-assets ember-dist static-dist +.PHONY: bin default prep test vet bootstrap fmt fmtcheck mysql-database-plugin mysql-legacy-database-plugin cassandra-database-plugin postgresql-database-plugin mssql-database-plugin hana-database-plugin mongodb-database-plugin static-assets ember-dist ember-dist-dev static-dist static-dist-dev diff --git a/ui/app/routes/vault/cluster/secrets/backend/list.js b/ui/app/routes/vault/cluster/secrets/backend/list.js index 10ccfcd4df..49ce0b0163 100644 --- a/ui/app/routes/vault/cluster/secrets/backend/list.js +++ b/ui/app/routes/vault/cluster/secrets/backend/list.js @@ -19,12 +19,16 @@ export default Ember.Route.extend({ templateName: 'vault/cluster/secrets/backend/list', beforeModel() { - const { backend } = this.paramsFor('vault.cluster.secrets.backend'); - const backendModel = this.store.peekRecord('secret-engine', backend); - const type = backendModel && backendModel.get('type'); + let { backend } = this.paramsFor('vault.cluster.secrets.backend'); + let { secret } = this.paramsFor(this.routeName); + let backendModel = this.store.peekRecord('secret-engine', backend); + let type = backendModel && backendModel.get('type'); if (!type || !SUPPORTED_BACKENDS.includes(type)) { return this.transitionTo('vault.cluster.secrets'); } + if (this.routeName === 'vault.cluster.secrets.backend.list' && !secret.endsWith('/')) { + return this.replaceWith('vault.cluster.secrets.backend.list', secret + '/'); + } }, getModelType(backend, tab) { diff --git a/ui/ember-cli-build.js b/ui/ember-cli-build.js index 74461efe3c..53ae309409 100644 --- a/ui/ember-cli-build.js +++ b/ui/ember-cli-build.js @@ -20,29 +20,25 @@ module.exports = function(defaults) { opengraph: false, twitter: false, windows: false, - yandex: false - } - } + yandex: false, + }, + }, }, codemirror: { - modes: ['javascript','ruby'], - keyMaps: ['sublime'] + modes: ['javascript', 'ruby'], + keyMaps: ['sublime'], }, babel: { - plugins: [ - 'transform-object-rest-spread' - ] + plugins: ['transform-object-rest-spread'], }, autoprefixer: { grid: true, - browsers: [ - "defaults", - "ie 11" - ] - } + browsers: ['defaults', 'ie 11'], + }, }); app.import('vendor/string-includes.js'); + app.import('node_modules/string.prototype.endswith/endswith.js'); app.import('node_modules/string.prototype.startswith/startswith.js'); app.import('node_modules/autosize/dist/autosize.js'); app.import('vendor/shims/autosize.js'); @@ -56,15 +52,11 @@ module.exports = function(defaults) { app.import('node_modules/Duration.js/duration.js'); app.import('node_modules/columnify/columnify.js', { - using: [ - { transformation: 'cjs', as: 'columnify' } - ] + using: [{ transformation: 'cjs', as: 'columnify' }], }); app.import('node_modules/yargs-parser/lib/tokenize-arg-string.js', { - using: [ - { transformation: 'cjs', as: 'yargs-parser-tokenizer' } - ] + using: [{ transformation: 'cjs', as: 'yargs-parser-tokenizer' }], }); // Use `app.import` to add additional libraries to the generated diff --git a/ui/package.json b/ui/package.json index 2e76c7deb4..ee6fc798ce 100644 --- a/ui/package.json +++ b/ui/package.json @@ -10,6 +10,7 @@ "repository": "", "scripts": { "build": "ember build -prod", + "build-dev": "ember build", "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 & ember test", @@ -97,7 +98,8 @@ "prettier-eslint-cli": "^4.2.1", "qunit-dom": "^0.6.2", "sass-svg-uri": "^1.0.0", - "string.prototype.startswith": "mathiasbynens/String.prototype.startsWith", + "string.prototype.endswith": "^0.2.0", + "string.prototype.startswith": "^0.2.0", "text-encoder-lite": "1.0.0", "yargs-parser": "^10.0.0" }, diff --git a/ui/tests/acceptance/secrets/backend/kv/secret-test.js b/ui/tests/acceptance/secrets/backend/kv/secret-test.js index 84cd464139..c4ca9fada4 100644 --- a/ui/tests/acceptance/secrets/backend/kv/secret-test.js +++ b/ui/tests/acceptance/secrets/backend/kv/secret-test.js @@ -55,3 +55,15 @@ test('version 1 performs the correct capabilities lookup', function(assert) { ); }); }); + +test('it redirects to the path ending in / for list pages', function(assert) { + const path = `foo/bar/kv-path-${new Date().getTime()}`; + listPage.visitRoot({ backend: 'secret' }); + listPage.create(); + editPage.createSecret(path, 'foo', 'bar'); + listPage.visit({ backend: 'secret', id: 'foo/bar' }); + andThen(() => { + assert.equal(currentRouteName(), 'vault.cluster.secrets.backend.list'); + assert.ok(currentURL().endsWith('/'), 'redirects to the path ending in a slash'); + }); +}); diff --git a/ui/yarn.lock b/ui/yarn.lock index ef658b3acd..3e939e3cb3 100644 --- a/ui/yarn.lock +++ b/ui/yarn.lock @@ -7946,9 +7946,13 @@ string-width@^2.0.0, string-width@^2.1.0: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" -string.prototype.startswith@mathiasbynens/String.prototype.startsWith: +string.prototype.endswith@^0.2.0: version "0.2.0" - resolved "https://codeload.github.com/mathiasbynens/String.prototype.startsWith/tar.gz/bb6f34bb8577ac95b6aef79a13a84297d6fae5a6" + resolved "https://registry.yarnpkg.com/string.prototype.endswith/-/string.prototype.endswith-0.2.0.tgz#a19c20dee51a98777e9a47e10f09be393b9bba75" + +string.prototype.startswith@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/string.prototype.startswith/-/string.prototype.startswith-0.2.0.tgz#da68982e353a4e9ac4a43b450a2045d1c445ae7b" string_decoder@0.10, string_decoder@~0.10.x: version "0.10.31"