mirror of
				https://github.com/optim-enterprises-bv/vault.git
				synced 2025-10-30 18:17:55 +00:00 
			
		
		
		
	KV Download Value Stringify Toggle (#23747)
* adds stringify toggle to masked-input download modal * updates stringify toggle copy and adds a test * adds changelog entry
This commit is contained in:
		
							
								
								
									
										3
									
								
								changelog/23747.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								changelog/23747.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | ```release-note:improvement | ||||||
|  | ui: Adds toggle to KV secrets engine value download modal to optionally stringify value in downloaded file | ||||||
|  | ``` | ||||||
| @@ -75,13 +75,25 @@ | |||||||
|     <M.Body> |     <M.Body> | ||||||
|       This download is |       This download is | ||||||
|       <strong>unencrypted</strong>. Are you sure you want to download this secret data as plaintext? |       <strong>unencrypted</strong>. Are you sure you want to download this secret data as plaintext? | ||||||
|  |  | ||||||
|  |       <div class="has-top-margin-m"> | ||||||
|  |         <Hds::Form::Toggle::Field | ||||||
|  |           checked={{this.stringifyDownload}} | ||||||
|  |           {{on "change" this.toggleStringifyDownload}} | ||||||
|  |           data-test-stringify-toggle | ||||||
|  |           as |F| | ||||||
|  |         > | ||||||
|  |           <F.Label>Stringify secret value</F.Label> | ||||||
|  |           <F.HelperText>Preserve formatting for JSON values.</F.HelperText> | ||||||
|  |         </Hds::Form::Toggle::Field> | ||||||
|  |       </div> | ||||||
|     </M.Body> |     </M.Body> | ||||||
|     <M.Footer as |F|> |     <M.Footer as |F|> | ||||||
|       <Hds::ButtonSet> |       <Hds::ButtonSet> | ||||||
|         <DownloadButton |         <DownloadButton | ||||||
|           @filename={{or @name "secret-value"}} |           @filename={{or @name "secret-value"}} | ||||||
|           @data={{@value}} |           @data={{@value}} | ||||||
|           @stringify={{true}} |           @stringify={{this.stringifyDownload}} | ||||||
|           @onSuccess={{fn (mut this.modalOpen) false}} |           @onSuccess={{fn (mut this.modalOpen) false}} | ||||||
|         /> |         /> | ||||||
|         <Hds::Button @text="Cancel" @color="secondary" {{on "click" F.close}} /> |         <Hds::Button @text="Cancel" @color="secondary" {{on "click" F.close}} /> | ||||||
|   | |||||||
| @@ -35,6 +35,7 @@ export default class MaskedInputComponent extends Component { | |||||||
|   textareaId = 'textarea-' + guidFor(this); |   textareaId = 'textarea-' + guidFor(this); | ||||||
|   @tracked showValue = false; |   @tracked showValue = false; | ||||||
|   @tracked modalOpen = false; |   @tracked modalOpen = false; | ||||||
|  |   @tracked stringifyDownload = false; | ||||||
|  |  | ||||||
|   constructor() { |   constructor() { | ||||||
|     super(...arguments); |     super(...arguments); | ||||||
| @@ -62,7 +63,12 @@ export default class MaskedInputComponent extends Component { | |||||||
|       this.args.onKeyUp(name, value); |       this.args.onKeyUp(name, value); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @action toggleMask() { |   @action toggleMask() { | ||||||
|     this.showValue = !this.showValue; |     this.showValue = !this.showValue; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @action toggleStringifyDownload(event) { | ||||||
|  |     this.stringifyDownload = event.target.checked; | ||||||
|  |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -130,4 +130,37 @@ module('Integration | Component | masked input', function (hooks) { | |||||||
|       .dom('[data-test-icon="minus"]') |       .dom('[data-test-icon="minus"]') | ||||||
|       .exists('shows minus icon when unmasked because value is empty string'); |       .exists('shows minus icon when unmasked because value is empty string'); | ||||||
|   }); |   }); | ||||||
|  |  | ||||||
|  |   test('it should render stringify toggle in download modal', async function (assert) { | ||||||
|  |     assert.expect(3); | ||||||
|  |  | ||||||
|  |     // this looks wonky but need a new line in there to test stringify adding escape character | ||||||
|  |     this.value = `bar | ||||||
|  | `; | ||||||
|  |  | ||||||
|  |     const downloadStub = sinon.stub(this.owner.lookup('service:download'), 'miscExtension'); | ||||||
|  |     downloadStub.callsFake((fileName, value) => { | ||||||
|  |       const firstCall = downloadStub.callCount === 1; | ||||||
|  |       const assertVal = firstCall ? this.value : JSON.stringify(this.value); | ||||||
|  |       assert.strictEqual(assertVal, value, `Value is ${firstCall ? 'not ' : ''}stringified`); | ||||||
|  |       return true; | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     await render(hbs` | ||||||
|  |       <MaskedInput | ||||||
|  |         @name="key" | ||||||
|  |         @value={{this.value}} | ||||||
|  |         @displayOnly={{true}} | ||||||
|  |         @allowDownload={{true}} | ||||||
|  |       /> | ||||||
|  |     `); | ||||||
|  |  | ||||||
|  |     await click('[data-test-download-icon]'); | ||||||
|  |     assert.dom('[data-test-stringify-toggle]').isNotChecked('Stringify toggle off as default'); | ||||||
|  |     await click('[data-test-download-button]'); | ||||||
|  |  | ||||||
|  |     await click('[data-test-download-icon]'); | ||||||
|  |     await click('[data-test-stringify-toggle]'); | ||||||
|  |     await click('[data-test-download-button]'); | ||||||
|  |   }); | ||||||
| }); | }); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Jordan Reimer
					Jordan Reimer