diff --git a/ui/app/adapters/secret-v2-version.js b/ui/app/adapters/secret-v2-version.js index 0d896f99a3..4f77992cdf 100644 --- a/ui/app/adapters/secret-v2-version.js +++ b/ui/app/adapters/secret-v2-version.js @@ -19,6 +19,11 @@ export default ApplicationAdapter.extend({ return this._url(backend, path) + `?version=${version}`; }, + urlForQueryRecord(id) { + let [backend, path, version] = JSON.parse(id); + return this._url(backend, path) + `?version=${version}`; + }, + findRecord() { return this._super(...arguments).catch(errorOrModel => { // if it's a real 404, this will be an error, if not @@ -30,6 +35,17 @@ export default ApplicationAdapter.extend({ }); }, + queryRecord(id, options) { + return this.ajax(this.urlForQueryRecord(id), 'GET', options).then(resp => { + if (options.wrapTTL) { + return resp; + } + resp.id = id; + resp.backend = backend; + return resp; + }); + }, + urlForCreateRecord(modelName, snapshot) { let backend = snapshot.belongsTo('secret').belongsTo('engine').id; let path = snapshot.attr('path'); diff --git a/ui/app/adapters/secret.js b/ui/app/adapters/secret.js index 30f2e5f3f6..d282d08e89 100644 --- a/ui/app/adapters/secret.js +++ b/ui/app/adapters/secret.js @@ -34,22 +34,29 @@ export default ApplicationAdapter.extend({ return url; }, - optionsForQuery(id, action) { + optionsForQuery(id, action, wrapTTL) { let data = {}; if (action === 'query') { - data['list'] = true; + data.list = true; + } + if (wrapTTL) { + return { data, wrapTTL }; } - return { data }; }, fetchByQuery(query, action) { - const { id, backend } = query; - return this.ajax(this.urlForSecret(backend, id), 'GET', this.optionsForQuery(id, action)).then(resp => { - resp.id = id; - resp.backend = backend; - return resp; - }); + const { id, backend, wrapTTL } = query; + return this.ajax(this.urlForSecret(backend, id), 'GET', this.optionsForQuery(id, action, wrapTTL)).then( + resp => { + if (wrapTTL) { + return resp; + } + resp.id = id; + resp.backend = backend; + return resp; + } + ); }, query(store, type, query) { diff --git a/ui/app/components/secret-edit.js b/ui/app/components/secret-edit.js index 0c93414bc3..59b5be8788 100644 --- a/ui/app/components/secret-edit.js +++ b/ui/app/components/secret-edit.js @@ -17,6 +17,7 @@ export default Component.extend(FocusOnInsertMixin, { wizard: service(), router: service(), store: service(), + flashMessages: service(), // a key model key: null, @@ -31,6 +32,10 @@ export default Component.extend(FocusOnInsertMixin, { secretData: null, + wrappedData: null, + isWrapping: false, + showWrapButton: computed.not('wrappedData'), + // called with a bool indicating if there's been a change in the secretData onDataChange() {}, onRefresh() {}, @@ -235,6 +240,53 @@ export default Component.extend(FocusOnInsertMixin, { set(this.modelForData, 'secretData', this.secretData.toJSON()); }, + handleWrapClick() { + this.set('isWrapping', true); + if (this.isV2) { + this.store + .adapterFor('secret-v2-version') + .queryRecord(this.modelForData.id, { wrapTTL: 1800 }) + .then(resp => { + this.set('wrappedData', resp.wrap_info.token); + this.flashMessages.success('Secret Successfully Wrapped!'); + }) + .catch(() => { + this.flashMessages.error('Could Not Wrap Secret'); + }) + .finally(() => { + this.set('isWrapping', false); + }); + } else { + this.store + .adapterFor('secret') + .queryRecord(null, null, { backend: this.model.backend, id: this.modelForData.id, wrapTTL: 1800 }) + .then(resp => { + this.set('wrappedData', resp.wrap_info.token); + this.flashMessages.success('Secret Successfully Wrapped!'); + }) + .catch(() => { + this.flashMessages.error('Could Not Wrap Secret'); + }) + .finally(() => { + this.set('isWrapping', false); + }); + } + }, + + clearWrappedData() { + this.set('wrappedData', null); + }, + + handleCopySuccess() { + this.flashMessages.success('Copied Wrapped Data!'); + this.send('clearWrappedData'); + }, + + handleCopyError() { + this.flashMessages.error('Could Not Copy Wrapped Data'); + this.send('clearWrappedData'); + }, + createOrUpdateKey(type, event) { event.preventDefault(); let model = this.modelForData; diff --git a/ui/app/components/tool-actions-form.js b/ui/app/components/tool-actions-form.js index e17d7ab74c..617b895ae8 100644 --- a/ui/app/components/tool-actions-form.js +++ b/ui/app/components/tool-actions-form.js @@ -14,6 +14,7 @@ const DEFAULTS = { creation_ttl: null, data: '{\n}', unwrap_data: null, + details: null, wrapTTL: null, sum: null, random_bytes: null, @@ -33,6 +34,7 @@ export default Component.extend(DEFAULTS, { algorithm: 'sha2-256', tagName: '', + unwrapActiveTab: 'data', didReceiveAttrs() { this._super(...arguments); @@ -76,7 +78,13 @@ export default Component.extend(DEFAULTS, { let props = {}; let secret = (resp && resp.data) || resp.auth; if (secret && action === 'unwrap') { - props = assign({}, props, { unwrap_data: secret }); + let details = { + 'Request ID': resp.request_id, + 'Lease ID': resp.lease_id || 'None', + Renewable: resp.renewable ? 'Yes' : 'No', + 'Lease Duration': resp.lease_duration || 'None', + }; + props = assign({}, props, { unwrap_data: secret }, { details: details }); } props = assign({}, props, secret); if (resp && resp.wrap_info) { diff --git a/ui/app/styles/components/masked-input.scss b/ui/app/styles/components/masked-input.scss index b7b65e5ff5..6018d0e324 100644 --- a/ui/app/styles/components/masked-input.scss +++ b/ui/app/styles/components/masked-input.scss @@ -12,6 +12,10 @@ padding-top: $spacing-s; } +.has-padding { + padding: $size-10 $size-8; +} + // we want to style the boxes the same everywhere so they // need to be the same font and small .masked-input.masked .masked-value { diff --git a/ui/app/styles/components/tabs.scss b/ui/app/styles/components/tabs.scss index ef0c844b7c..a586fd093c 100644 --- a/ui/app/styles/components/tabs.scss +++ b/ui/app/styles/components/tabs.scss @@ -3,22 +3,23 @@ ul { border-color: transparent; + min-height: 3rem; } li { &:focus { box-shadow: none; } - &.is-active a { + &.is-active a, &.is-active .tab { border-color: $blue; color: $blue; } - &:first-child a { + &:first-child a, &:first-child .tab { margin-left: $size-5; } } - a { + a, .tab { color: $grey-dark; font-weight: $font-weight-semibold; text-decoration: none; diff --git a/ui/app/templates/components/masked-input.hbs b/ui/app/templates/components/masked-input.hbs index 2976df52a0..c60a3432d0 100644 --- a/ui/app/templates/components/masked-input.hbs +++ b/ui/app/templates/components/masked-input.hbs @@ -19,6 +19,7 @@