Ui/transit key actions textareas (#8462)
* feat: update transit textareas to codeblocks & automatically encode plaintext to base64 unless marked as encoded
This commit is contained in:
parent
c7986d119c
commit
6f6f1d9fd8
|
@ -12,6 +12,7 @@
|
|||
/.storybook/
|
||||
/.yarn/
|
||||
/stories/
|
||||
/storybook-static/
|
||||
|
||||
# misc
|
||||
/coverage/
|
||||
|
|
|
@ -4,6 +4,7 @@ import { assert } from '@ember/debug';
|
|||
import { inject as service } from '@ember/service';
|
||||
import Component from '@ember/component';
|
||||
import { set, get, computed } from '@ember/object';
|
||||
import { encodeString } from 'vault/utils/b64';
|
||||
|
||||
const TRANSIT_PARAMS = {
|
||||
hash_algorithm: 'sha2-256',
|
||||
|
@ -25,6 +26,7 @@ const TRANSIT_PARAMS = {
|
|||
random_bytes: null,
|
||||
signature: null,
|
||||
sum: null,
|
||||
encodedBase64: false,
|
||||
exportKeyType: null,
|
||||
exportKeyVersion: null,
|
||||
wrappedToken: null,
|
||||
|
@ -185,7 +187,16 @@ export default Component.extend(TRANSIT_PARAMS, {
|
|||
doSubmit(data, options = {}) {
|
||||
const { backend, id } = this.getModelInfo();
|
||||
const action = this.get('selectedAction');
|
||||
let payload = data ? this.compactData(data) : null;
|
||||
const { encodedBase64, ...formData } = data || {};
|
||||
if (!encodedBase64) {
|
||||
if (action === 'encrypt' && !!formData.plaintext) {
|
||||
formData.plaintext = encodeString(formData.plaintext);
|
||||
}
|
||||
if ((action === 'hmac' || action === 'verify') && !!formData.input) {
|
||||
formData.input = encodeString(formData.input);
|
||||
}
|
||||
}
|
||||
let payload = formData ? this.compactData(formData) : null;
|
||||
this.setProperties({
|
||||
errors: null,
|
||||
result: null,
|
||||
|
|
|
@ -5,8 +5,18 @@
|
|||
<label for="plaintext" class="is-label">
|
||||
Plaintext
|
||||
</label>
|
||||
<div class="control is-relative">
|
||||
{{textarea id="plaintext" value=plaintext readonly=true class="textarea" data-test-transit-input="plaintext"}}
|
||||
<div id="plaintext-control" class="control is-relative">
|
||||
{{ivy-codemirror
|
||||
value=plaintext
|
||||
options=(hash
|
||||
readOnly=true
|
||||
lineNumbers=true
|
||||
tabSize=2
|
||||
mode='ruby'
|
||||
theme='hashi'
|
||||
)
|
||||
data-test-transit-input="plaintext"
|
||||
}}
|
||||
{{b64-toggle value=plaintext isInput=false initialEncoding="base64" data-test-transit-b64-toggle="plaintext"}}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -32,8 +42,18 @@
|
|||
<div class="box is-sideless is-fullwidth is-marginless">
|
||||
<div class="field">
|
||||
<label for="ciphertext" class="is-label">Ciphertext</label>
|
||||
<div class="control">
|
||||
{{textarea id="ciphertext" name="ciphertext" value=ciphertext class="textarea" data-test-transit-input="ciphertext"}}
|
||||
<div id="ciphertext-control" class="control">
|
||||
{{ivy-codemirror
|
||||
value=ciphertext
|
||||
valueUpdated=(action (mut ciphertext))
|
||||
options=(hash
|
||||
lineNumbers=true
|
||||
tabSize=2
|
||||
mode='ruby'
|
||||
theme='hashi'
|
||||
)
|
||||
data-test-transit-input="ciphertext"
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
{{#if key.derived}}
|
||||
|
|
|
@ -1,17 +1,27 @@
|
|||
<form {{action 'doSubmit' (hash plaintext=plaintext context=context nonce=nonce key_version=key_version) on="submit"}}>
|
||||
<form {{action 'doSubmit' (hash plaintext=plaintext context=context nonce=nonce key_version=key_version encodedBase64=encodedBase64) on="submit"}}>
|
||||
{{#if (and plaintext ciphertext)}}
|
||||
<div class="box is-sideless is-fullwidth is-marginless">
|
||||
<div class="field">
|
||||
<label for="ciphertext" class="is-label">Ciphertext</label>
|
||||
<div class="control is-expanded">
|
||||
<textarea readonly class="textarea" id="ciphertext" data-test-transit-input="ciphertext">{{ciphertext}}</textarea>
|
||||
<div id="ciphertext-control" class="control is-expanded">
|
||||
{{ivy-codemirror
|
||||
value=ciphertext
|
||||
options=(hash
|
||||
readOnly=true
|
||||
lineNumbers=true
|
||||
tabSize=2
|
||||
mode='ruby'
|
||||
theme='hashi'
|
||||
)
|
||||
data-test-transit-input="ciphertext"
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field is-grouped box is-fullwidth is-bottomless">
|
||||
<div class="control">
|
||||
{{#copy-button
|
||||
clipboardTarget="#ciphertext"
|
||||
clipboardText=ciphertext
|
||||
class="button is-primary"
|
||||
buttonType="button"
|
||||
success=(action (set-flash-message 'Ciphertext copied!'))
|
||||
|
@ -20,7 +30,7 @@
|
|||
{{/copy-button}}
|
||||
</div>
|
||||
<div class="control">
|
||||
<button {{action "onClear"}} type="button" class="button">
|
||||
<button {{action "onClear"}} type="button" class="button" data-test-encrypt-back-button>
|
||||
Back
|
||||
</button>
|
||||
</div>
|
||||
|
@ -37,11 +47,24 @@
|
|||
<label for="plaintext" class="is-label">
|
||||
Plaintext
|
||||
</label>
|
||||
<div class="control is-relative">
|
||||
{{textarea id="plaintext" value=plaintext class="textarea" data-test-transit-input="plaintext"}}
|
||||
{{b64-toggle value=plaintext isInput=false data-test-transit-b64-toggle="plaintext"}}
|
||||
<div id="plaintext-control" class="control is-relative">
|
||||
{{ivy-codemirror
|
||||
value=plaintext
|
||||
valueUpdated=(action (mut plaintext))
|
||||
options=(hash
|
||||
lineNumbers=true
|
||||
tabSize=2
|
||||
mode='ruby'
|
||||
theme='hashi'
|
||||
)
|
||||
data-test-transit-input="plaintext"
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
{{input type="checkbox" id="encodedBase64" checked=encodedBase64 data-test-transit-input="encodedBase64"}}
|
||||
<label for="encodedBase64">This data is already encoded in base64</label>
|
||||
</div>
|
||||
{{#if key.derived}}
|
||||
<div class="field">
|
||||
<label for="context" class="is-label">
|
||||
|
|
|
@ -3,15 +3,24 @@
|
|||
<div class="box is-sideless is-fullwidth is-marginless">
|
||||
<div class="field">
|
||||
<label for="hmac" class="is-label">HMAC</label>
|
||||
<div class="control">
|
||||
<textarea readonly class="textarea" id="hmac">{{hmac}}</textarea>
|
||||
<div id="hmac-control" class="control">
|
||||
{{ivy-codemirror
|
||||
value=hmac
|
||||
options=(hash
|
||||
readOnly=true
|
||||
lineNumbers=true
|
||||
tabSize=2
|
||||
mode='ruby'
|
||||
theme='hashi'
|
||||
)
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field is-grouped box is-fullwidth is-bottomless">
|
||||
<div class="control">
|
||||
{{#copy-button
|
||||
clipboardTarget="#hmac"
|
||||
clipboardText=hmac
|
||||
class="button is-primary"
|
||||
buttonType="button"
|
||||
success=(action (set-flash-message 'HMAC copied!'))
|
||||
|
@ -37,11 +46,28 @@
|
|||
<label for="input" class="is-label">
|
||||
Input
|
||||
</label>
|
||||
<div class="control is-relative">
|
||||
{{textarea id="input" name="input" value=input class="textarea" data-test-transit-input="input"}}
|
||||
{{b64-toggle value=input isInput=false data-test-transit-b64-toggle="input"}}
|
||||
<div id="input-control" class="control is-relative">
|
||||
{{ivy-codemirror
|
||||
value=input
|
||||
valueUpdated=(action (mut input))
|
||||
options=(hash
|
||||
lineNumbers=true
|
||||
tabSize=2
|
||||
mode='ruby'
|
||||
theme='hashi'
|
||||
)
|
||||
data-test-transit-input="input"
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
{{input
|
||||
type="checkbox"
|
||||
id="encodedBase64"
|
||||
checked=encodedBase64
|
||||
data-test-transit-input="encodedBase64" }}
|
||||
<label for="encodedBase64">This data is already encoded in base64</label>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="algorithm" class="is-label">Hash Algorithm</label>
|
||||
<div class="control is-expanded">
|
||||
|
|
|
@ -9,7 +9,16 @@
|
|||
<div class="field">
|
||||
<label for="ciphertext" class="is-label">Ciphertext</label>
|
||||
<div class="control is-expanded">
|
||||
{{textarea name="ciphertext" class="textarea" id="ciphertext" value=ciphertext}}
|
||||
{{ivy-codemirror
|
||||
value=ciphertext
|
||||
valueUpdated=(action (mut ciphertext))
|
||||
options=(hash
|
||||
lineNumbers=true
|
||||
tabSize=2
|
||||
mode='ruby'
|
||||
theme='hashi'
|
||||
)
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
{{#if key.derived}}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<form {{action "doSubmit" (hash input=input signature=signature signature_algorithm=signature_algorithm hmac=hmac hash_algorithm=hash_algorithm context=context prehashed=prehashed) on="submit"}}>
|
||||
<form {{action "doSubmit" (hash input=input signature=signature signature_algorithm=signature_algorithm hmac=hmac hash_algorithm=hash_algorithm context=context prehashed=prehashed encodedBase64=encodedBase64) on="submit"}}>
|
||||
{{#if (not-eq valid null)}}
|
||||
<div class="box is-sideless is-fullwidth is-marginless">
|
||||
<h4 class="is-label">Verified</h4>
|
||||
|
@ -25,10 +25,24 @@
|
|||
Input
|
||||
</label>
|
||||
<div class="control is-relative">
|
||||
{{textarea id="input" name="input" value=input class="textarea" data-test-transit-input="input"}}
|
||||
{{b64-toggle value=input isInput=false data-test-transit-b64-toggle="input"}}
|
||||
{{ivy-codemirror
|
||||
id="input"
|
||||
value=input
|
||||
valueUpdated=(action (mut input))
|
||||
options=(hash
|
||||
lineNumbers=true
|
||||
tabSize=2
|
||||
mode='ruby'
|
||||
theme='hashi'
|
||||
)
|
||||
data-test-transit-input="input"
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
{{input type="checkbox" id="encodedBase64" checked=encodedBase64 data-test-transit-input="encodedBase64"}}
|
||||
<label for="encodedBase64">This data is already encoded in base64</label>
|
||||
</div>
|
||||
{{#if (and key.supportsSigning key.derived (not hmac))}}
|
||||
<div class="field">
|
||||
<label for="context" class="is-label">
|
||||
|
@ -76,7 +90,12 @@
|
|||
<div class="level-right">
|
||||
{{#unless (eq verification 'HMAC')}}
|
||||
<div class="control is-flex">
|
||||
{{input id="prehashed" type="checkbox" name="prehashed" class="switch is-rounded is-success is-small" checked=prehashed }}
|
||||
{{input
|
||||
id="prehashed"
|
||||
type="checkbox"
|
||||
name="prehashed"
|
||||
class="switch is-rounded is-success is-small"
|
||||
checked=prehashed }}
|
||||
<label for="prehashed">Prehashed</label>
|
||||
</div>
|
||||
{{/unless}}
|
||||
|
@ -126,14 +145,34 @@
|
|||
<div class="field is-flex-column is-flex-1">
|
||||
<label for="hmac" class="is-label">HMAC</label>
|
||||
<div class="control is-flex-column is-flex-1">
|
||||
{{textarea class="textarea is-flex-1" id="hmac" value=hmac}}
|
||||
{{ivy-codemirror
|
||||
id="hmac"
|
||||
value=hmac
|
||||
valueUpdated=(action (mut hmac))
|
||||
options=(hash
|
||||
lineNumbers=true
|
||||
tabSize=2
|
||||
mode='ruby'
|
||||
theme='hashi'
|
||||
)
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="field is-flex-column is-flex-1">
|
||||
<label for="signature" class="is-label">Signature</label>
|
||||
<div class="control is-flex-column is-flex-1">
|
||||
{{textarea id="signature" class="textarea is-flex-1" value=signature}}
|
||||
{{ivy-codemirror
|
||||
id="signature"
|
||||
value=signature
|
||||
valueUpdated=(action (mut signature))
|
||||
options=(hash
|
||||
lineNumbers=true
|
||||
tabSize=2
|
||||
mode='ruby'
|
||||
theme='hashi'
|
||||
)
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
@ -143,7 +182,17 @@
|
|||
<div class="field">
|
||||
<label for="hmac" class="is-label">HMAC</label>
|
||||
<div class="control">
|
||||
{{textarea class="textarea" id="hmac" value=hmac}}
|
||||
{{ivy-codemirror
|
||||
id="hmac"
|
||||
value=hmac
|
||||
valueUpdated=(action (mut hmac))
|
||||
options=(hash
|
||||
lineNumbers=true
|
||||
tabSize=2
|
||||
mode='ruby'
|
||||
theme='hashi'
|
||||
)
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
|
|
|
@ -97,7 +97,7 @@ const testConvergentEncryption = async function(assert, keyName) {
|
|||
decodeAfterDecrypt: false,
|
||||
assertAfterEncrypt: key => {
|
||||
assert.ok(
|
||||
/vault:/.test(find('[data-test-transit-input="ciphertext"]').value),
|
||||
/vault:/.test(find('#ciphertext-control .CodeMirror').CodeMirror.getValue()),
|
||||
`${key}: ciphertext shows a vault-prefixed ciphertext`
|
||||
);
|
||||
},
|
||||
|
@ -111,12 +111,11 @@ const testConvergentEncryption = async function(assert, keyName) {
|
|||
},
|
||||
|
||||
assertAfterDecrypt: key => {
|
||||
assert
|
||||
.dom('[data-test-transit-input="plaintext"]')
|
||||
.hasValue(
|
||||
'NaXud2QW7KjyK6Me9ggh+zmnCeBGdG93LQED49PtoOI=',
|
||||
`${key}: the ui shows the base64-encoded plaintext`
|
||||
);
|
||||
assert.equal(
|
||||
find('#plaintext-control .CodeMirror').CodeMirror.getValue(),
|
||||
'NaXud2QW7KjyK6Me9ggh+zmnCeBGdG93LQED49PtoOI=',
|
||||
`${key}: the ui shows the base64-encoded plaintext`
|
||||
);
|
||||
},
|
||||
},
|
||||
// raw bytes for plaintext, string for context
|
||||
|
@ -128,7 +127,7 @@ const testConvergentEncryption = async function(assert, keyName) {
|
|||
decodeAfterDecrypt: false,
|
||||
assertAfterEncrypt: key => {
|
||||
assert.ok(
|
||||
/vault:/.test(find('[data-test-transit-input="ciphertext"]').value),
|
||||
/vault:/.test(find('#ciphertext-control .CodeMirror').CodeMirror.getValue()),
|
||||
`${key}: ciphertext shows a vault-prefixed ciphertext`
|
||||
);
|
||||
},
|
||||
|
@ -138,12 +137,11 @@ const testConvergentEncryption = async function(assert, keyName) {
|
|||
.hasValue(encodeString('context'), `${key}: the ui shows the input context`);
|
||||
},
|
||||
assertAfterDecrypt: key => {
|
||||
assert
|
||||
.dom('[data-test-transit-input="plaintext"]')
|
||||
.hasValue(
|
||||
'NaXud2QW7KjyK6Me9ggh+zmnCeBGdG93LQED49PtoOI=',
|
||||
`${key}: the ui shows the base64-encoded plaintext`
|
||||
);
|
||||
assert.equal(
|
||||
find('#plaintext-control .CodeMirror').CodeMirror.getValue(),
|
||||
'NaXud2QW7KjyK6Me9ggh+zmnCeBGdG93LQED49PtoOI=',
|
||||
`${key}: the ui shows the base64-encoded plaintext`
|
||||
);
|
||||
},
|
||||
},
|
||||
// base64 input
|
||||
|
@ -155,7 +153,7 @@ const testConvergentEncryption = async function(assert, keyName) {
|
|||
decodeAfterDecrypt: true,
|
||||
assertAfterEncrypt: key => {
|
||||
assert.ok(
|
||||
/vault:/.test(find('[data-test-transit-input="ciphertext"]').value),
|
||||
/vault:/.test(find('#ciphertext-control .CodeMirror').CodeMirror.getValue()),
|
||||
`${key}: ciphertext shows a vault-prefixed ciphertext`
|
||||
);
|
||||
},
|
||||
|
@ -165,9 +163,11 @@ const testConvergentEncryption = async function(assert, keyName) {
|
|||
.hasValue(encodeString('context'), `${key}: the ui shows the input context`);
|
||||
},
|
||||
assertAfterDecrypt: key => {
|
||||
assert
|
||||
.dom('[data-test-transit-input="plaintext"]')
|
||||
.hasValue('This is the secret', `${key}: the ui decodes plaintext`);
|
||||
assert.equal(
|
||||
find('#plaintext-control .CodeMirror').CodeMirror.getValue(),
|
||||
'This is the secret',
|
||||
`${key}: the ui decodes plaintext`
|
||||
);
|
||||
},
|
||||
},
|
||||
|
||||
|
@ -181,7 +181,7 @@ const testConvergentEncryption = async function(assert, keyName) {
|
|||
assertAfterEncrypt: key => {
|
||||
assert.ok(find('[data-test-transit-input="ciphertext"]'), `${key}: ciphertext box shows`);
|
||||
assert.ok(
|
||||
/vault:/.test(find('[data-test-transit-input="ciphertext"]').value),
|
||||
/vault:/.test(find('#ciphertext-control .CodeMirror').CodeMirror.getValue()),
|
||||
`${key}: ciphertext shows a vault-prefixed ciphertext`
|
||||
);
|
||||
},
|
||||
|
@ -192,19 +192,22 @@ const testConvergentEncryption = async function(assert, keyName) {
|
|||
},
|
||||
assertAfterDecrypt: key => {
|
||||
assert.ok(find('[data-test-transit-input="plaintext"]'), `${key}: plaintext box shows`);
|
||||
assert
|
||||
.dom('[data-test-transit-input="plaintext"]')
|
||||
.hasValue('There are many secrets 🤐', `${key}: the ui decodes plaintext`);
|
||||
assert.equal(
|
||||
find('#plaintext-control .CodeMirror').CodeMirror.getValue(),
|
||||
'There are many secrets 🤐',
|
||||
`${key}: the ui decodes plaintext`
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
for (let testCase of tests) {
|
||||
await click('[data-test-transit-action-link="encrypt"]');
|
||||
await fillIn('[data-test-transit-input="plaintext"]', testCase.plaintext);
|
||||
find('#plaintext-control .CodeMirror').CodeMirror.setValue(testCase.plaintext);
|
||||
await fillIn('[data-test-transit-input="context"]', testCase.context);
|
||||
if (testCase.encodePlaintext) {
|
||||
await click('[data-test-transit-b64-toggle="plaintext"]');
|
||||
if (!testCase.encodePlaintext) {
|
||||
// If value is already encoded, check the box
|
||||
await click('input[data-test-transit-input="encodedBase64"]');
|
||||
}
|
||||
if (testCase.encodeContext) {
|
||||
await click('[data-test-transit-b64-toggle="context"]');
|
||||
|
|
|
@ -119,8 +119,7 @@ module('Integration | Component | transit key actions', function(hooks) {
|
|||
this.set('storeService.keyActionReturnVal', { ciphertext: 'secret' });
|
||||
await render(hbs`{{transit-key-actions selectedAction=selectedAction key=key}}`);
|
||||
|
||||
await fillIn('#plaintext', 'plaintext');
|
||||
await click('[data-test-transit-b64-toggle="plaintext"]');
|
||||
find('#plaintext-control .CodeMirror').CodeMirror.setValue('plaintext');
|
||||
await click('button[type="submit"]');
|
||||
assert.deepEqual(
|
||||
this.get('storeService.callArgs'),
|
||||
|
@ -135,7 +134,28 @@ module('Integration | Component | transit key actions', function(hooks) {
|
|||
'passes expected args to the adapter'
|
||||
);
|
||||
|
||||
assert.equal(find('#ciphertext').value, 'secret');
|
||||
assert.equal(find('#ciphertext-control .CodeMirror').CodeMirror.getValue(), 'secret');
|
||||
|
||||
const preEncodedValue = encodeString('plaintext');
|
||||
// Click back button
|
||||
await click('[data-test-encrypt-back-button]');
|
||||
// Encrypt again, with pre-encoded value and checkbox selected
|
||||
find('#plaintext-control .CodeMirror').CodeMirror.setValue(preEncodedValue);
|
||||
await click('input[data-test-transit-input="encodedBase64"]');
|
||||
await click('button[type="submit"]');
|
||||
|
||||
assert.deepEqual(
|
||||
this.get('storeService.callArgs'),
|
||||
{
|
||||
action: 'encrypt',
|
||||
backend: 'transit',
|
||||
id: 'akey',
|
||||
payload: {
|
||||
plaintext: preEncodedValue,
|
||||
},
|
||||
},
|
||||
'passes expected args to the adapter'
|
||||
);
|
||||
}
|
||||
|
||||
test('it encrypts', doEncrypt);
|
||||
|
@ -148,8 +168,7 @@ module('Integration | Component | transit key actions', function(hooks) {
|
|||
this.set('storeService.keyActionReturnVal', { ciphertext: 'secret' });
|
||||
await render(hbs`{{transit-key-actions selectedAction="encrypt" key=key}}`);
|
||||
|
||||
await fillIn('#plaintext', 'plaintext');
|
||||
await click('[data-test-transit-b64-toggle="plaintext"]');
|
||||
findAll('.CodeMirror')[0].CodeMirror.setValue('plaintext');
|
||||
assert.equal(findAll('#key_version').length, 1, 'it renders the key version selector');
|
||||
|
||||
await triggerEvent('#key_version', 'change');
|
||||
|
@ -177,9 +196,8 @@ module('Integration | Component | transit key actions', function(hooks) {
|
|||
this.set('storeService.keyActionReturnVal', { ciphertext: 'secret' });
|
||||
await render(hbs`{{transit-key-actions selectedAction="encrypt" key=key}}`);
|
||||
|
||||
await fillIn('#plaintext', 'plaintext');
|
||||
await click('[data-test-transit-b64-toggle="plaintext"]');
|
||||
|
||||
// await fillIn('#plaintext', 'plaintext');
|
||||
find('#plaintext-control .CodeMirror').CodeMirror.setValue('plaintext');
|
||||
assert.equal(
|
||||
findAll('#key_version').length,
|
||||
0,
|
||||
|
@ -193,10 +211,18 @@ module('Integration | Component | transit key actions', function(hooks) {
|
|||
|
||||
this.set('storeService.keyActionReturnVal', { plaintext });
|
||||
this.set('selectedAction', 'decrypt');
|
||||
assert.equal(find('#ciphertext').value, 'secret', 'keeps ciphertext value');
|
||||
assert.equal(
|
||||
find('#ciphertext-control .CodeMirror').CodeMirror.getValue(),
|
||||
'secret',
|
||||
'keeps ciphertext value'
|
||||
);
|
||||
|
||||
await click('button[type="submit"]');
|
||||
assert.equal(find('#plaintext').value, plaintext, 'renders decrypted value');
|
||||
assert.equal(
|
||||
find('#plaintext-control .CodeMirror').CodeMirror.getValue(),
|
||||
plaintext,
|
||||
'renders decrypted value'
|
||||
);
|
||||
});
|
||||
|
||||
const setupExport = async function() {
|
||||
|
|
Loading…
Reference in New Issue