mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-10-30 02:02:43 +00:00
UI: Fix KV v2 json editor (#24224)
* Fix JSON editor in KVv2 unable to paste. Fixes #23940 * Default to JSON view on edit with secret is complex * Add changelog
This commit is contained in:
3
changelog/24224.txt
Normal file
3
changelog/24224.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
```release-note:bug
|
||||
ui: Fix JSON editor in KV V2 unable to handle pasted values
|
||||
```
|
||||
@@ -15,7 +15,7 @@
|
||||
{{#if @showJson}}
|
||||
<JsonEditor
|
||||
@title="{{if @isEdit 'Version' 'Secret'}} data"
|
||||
@value={{or (stringify @secret.secretData) this.emptyJson}}
|
||||
@value={{this.codeMirrorString}}
|
||||
@valueUpdated={{this.handleJson}}
|
||||
/>
|
||||
{{#if (or @modelValidations.secretData.errors this.lintingErrors)}}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import Component from '@glimmer/component';
|
||||
import { action } from '@ember/object';
|
||||
import { tracked } from '@glimmer/tracking';
|
||||
import KVObject from 'vault/lib/kv-object';
|
||||
import { stringify } from 'core/helpers/stringify';
|
||||
|
||||
/**
|
||||
* @module KvDataFields is used for rendering the fields associated with kv secret data, it hides/shows a json editor and renders validation errors for the json editor
|
||||
@@ -28,10 +28,13 @@ import KVObject from 'vault/lib/kv-object';
|
||||
|
||||
export default class KvDataFields extends Component {
|
||||
@tracked lintingErrors;
|
||||
@tracked codeMirrorString;
|
||||
|
||||
get emptyJson() {
|
||||
// if secretData is null, this specially formats a blank object and renders a nice initial state for the json editor
|
||||
return KVObject.create({ content: [{ name: '', value: '' }] }).toJSONString(true);
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.codeMirrorString = this.args.secret?.secretData
|
||||
? stringify([this.args.secret.secretData], {})
|
||||
: '{ "": "" }';
|
||||
}
|
||||
|
||||
@action
|
||||
@@ -41,5 +44,6 @@ export default class KvDataFields extends Component {
|
||||
if (!this.lintingErrors) {
|
||||
this.args.secret.secretData = JSON.parse(value);
|
||||
}
|
||||
this.codeMirrorString = value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,12 @@
|
||||
|
||||
<KvPageHeader @breadcrumbs={{@breadcrumbs}} @pageTitle="Create New Version">
|
||||
<:toolbarFilters>
|
||||
<Toggle @name="json" @checked={{this.showJsonView}} @onChange={{fn (mut this.showJsonView)}}>
|
||||
<Toggle
|
||||
@name="json"
|
||||
@checked={{or this.showJsonView this.secretDataIsAdvanced}}
|
||||
@onChange={{fn (mut this.showJsonView)}}
|
||||
@disabled={{this.secretDataIsAdvanced}}
|
||||
>
|
||||
<span class="has-text-grey">JSON</span>
|
||||
</Toggle>
|
||||
</:toolbarFilters>
|
||||
@@ -38,7 +43,7 @@
|
||||
<MessageError @model={{@secret}} @errorMessage={{this.errorMessage}} />
|
||||
|
||||
<KvDataFields
|
||||
@showJson={{this.showJsonView}}
|
||||
@showJson={{or this.showJsonView this.secretDataIsAdvanced}}
|
||||
@secret={{@secret}}
|
||||
@modelValidations={{this.modelValidations}}
|
||||
@isEdit={{true}}
|
||||
|
||||
@@ -38,10 +38,15 @@ export default class KvSecretEdit extends Component {
|
||||
@tracked modelValidations;
|
||||
@tracked invalidFormAlert;
|
||||
originalSecret;
|
||||
secretDataIsAdvanced;
|
||||
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.originalSecret = JSON.stringify(this.args.secret.secretData || {});
|
||||
if (this.originalSecret.lastIndexOf('{') > 0) {
|
||||
// Dumb way to check if there's a nested object in the secret
|
||||
this.secretDataIsAdvanced = true;
|
||||
}
|
||||
}
|
||||
|
||||
get showOldVersionAlert() {
|
||||
|
||||
@@ -24,6 +24,7 @@ import {
|
||||
} from 'vault/tests/helpers/policy-generator/kv';
|
||||
import { clearRecords, writeSecret, writeVersionedSecret } from 'vault/tests/helpers/kv/kv-run-commands';
|
||||
import { FORM, PAGE } from 'vault/tests/helpers/kv/kv-selectors';
|
||||
import codemirror from 'vault/tests/helpers/codemirror';
|
||||
|
||||
/**
|
||||
* This test set is for testing edge cases, such as specific bug fixes or reported user workflows
|
||||
@@ -269,6 +270,20 @@ module('Acceptance | kv-v2 workflow | edge cases', function (hooks) {
|
||||
await click(PAGE.breadcrumbAtIdx(2));
|
||||
assert.dom(PAGE.list.item()).exists({ count: 2 }, 'two secrets are listed');
|
||||
});
|
||||
|
||||
test('complex values default to JSON display', async function (assert) {
|
||||
await visit(`/vault/secrets/${this.backend}/kv/create`);
|
||||
await fillIn(FORM.inputByAttr('path'), 'complex');
|
||||
|
||||
await click(FORM.toggleJson);
|
||||
assert.strictEqual(codemirror().getValue(), '{ "": "" }');
|
||||
codemirror().setValue('{ "foo3": { "name": "bar3" } }');
|
||||
await click(FORM.saveBtn);
|
||||
// Future: test that json is automatic on details too
|
||||
await click(PAGE.detail.createNewVersion);
|
||||
assert.dom(FORM.toggleJson).isDisabled();
|
||||
assert.dom(FORM.toggleJson).isChecked();
|
||||
});
|
||||
});
|
||||
|
||||
// NAMESPACE TESTS
|
||||
|
||||
@@ -43,7 +43,7 @@ module('Integration | Component | kv-v2 | KvDataFields', function (hooks) {
|
||||
|
||||
assert.strictEqual(
|
||||
codemirror().getValue(' '),
|
||||
`{ \"\": \"\" }`, // eslint-disable-line no-useless-escape
|
||||
`{ \"\": \"\" }`, // eslint-disable-line no-useless-escape
|
||||
'json editor initializes with empty object'
|
||||
);
|
||||
await fillIn(`${FORM.jsonEditor} textarea`, 'blah');
|
||||
|
||||
Reference in New Issue
Block a user