diff --git a/ui/app/adapters/transform.js b/ui/app/adapters/transform.js
index ffc6f3820164..e1c2ad888b70 100644
--- a/ui/app/adapters/transform.js
+++ b/ui/app/adapters/transform.js
@@ -28,7 +28,7 @@ export default ApplicationAdapter.extend({
deleteRecord(store, type, snapshot) {
const { id } = snapshot;
- return this.ajax(this.urlForRole(snapshot.record.get('backend'), id), 'DELETE');
+ return this.ajax(this.urlForTransformations(snapshot.record.get('backend'), id), 'DELETE');
},
pathForType() {
@@ -63,9 +63,10 @@ export default ApplicationAdapter.extend({
const { id, backend } = query;
let zeroAddressAjax = resolve();
const queryAjax = this.ajax(this.urlForTransformations(backend, id), 'GET', this.optionsForQuery(id));
- if (!id) {
- zeroAddressAjax = this.findAllZeroAddress(store, query);
- }
+ // TODO: come back to why you need this, carry over.
+ // if (!id) {
+ // zeroAddressAjax = this.findAllZeroAddress(store, query);
+ // }
return allSettled([queryAjax, zeroAddressAjax]).then(results => {
// query result 404d, so throw the adapterError
diff --git a/ui/app/components/role-edit.js b/ui/app/components/role-edit.js
index 88270bc367d6..f2f27cc93ac5 100644
--- a/ui/app/components/role-edit.js
+++ b/ui/app/components/role-edit.js
@@ -89,7 +89,7 @@ export default Component.extend(FocusOnInsertMixin, {
createOrUpdate(type, event) {
event.preventDefault();
- const modelId = this.get('model.id') || this.get('model.name'); //ARG TODO this is not okay
+ const modelId = this.get('model.id') || this.get('model.name'); // ARG TODO this is not okay
// prevent from submitting if there's no key
// maybe do something fancier later
if (type === 'create' && isBlank(modelId)) {
diff --git a/ui/app/components/transform-show-transformation.js b/ui/app/components/transform-show-transformation.js
new file mode 100644
index 000000000000..d15a8a29f2e1
--- /dev/null
+++ b/ui/app/components/transform-show-transformation.js
@@ -0,0 +1,8 @@
+import RoleEdit from './role-edit';
+
+export default RoleEdit.extend({
+ init() {
+ this._super(...arguments);
+ this.set('backendType', 'transform');
+ },
+});
diff --git a/ui/app/helpers/options-for-backend.js b/ui/app/helpers/options-for-backend.js
index ff7f72735fad..68bd08c47ba4 100644
--- a/ui/app/helpers/options-for-backend.js
+++ b/ui/app/helpers/options-for-backend.js
@@ -59,7 +59,7 @@ const SECRET_BACKENDS = {
transform: {
displayName: 'Transformation',
navigateTree: false,
- listItemPartial: 'partials/secret-list/item',
+ listItemPartial: 'partials/secret-list/transform-transformation-item',
tabs: [
{
name: 'transformations',
diff --git a/ui/app/models/transform.js b/ui/app/models/transform.js
index 77360af2582b..d8637656f81a 100644
--- a/ui/app/models/transform.js
+++ b/ui/app/models/transform.js
@@ -1,8 +1,8 @@
-import { alias } from '@ember/object/computed';
import { computed } from '@ember/object';
import DS from 'ember-data';
-import lazyCapabilities, { apiPath } from 'vault/macros/lazy-capabilities';
+import { apiPath } from 'vault/macros/lazy-capabilities';
import { expandAttributeMeta } from 'vault/utils/field-to-attrs';
+import attachCapabilities from 'vault/lib/attach-capabilities';
const { attr } = DS;
@@ -35,11 +35,10 @@ const TWEAK_SOURCE = [
},
];
-export default DS.Model.extend({
+const Model = DS.Model.extend({
// TODO: for now, commenting out openApi info, but keeping here just in case we end up using it.
// useOpenAPI: true,
// getHelpUrl: function(backend) {
- // console.log(backend, 'Backend');
// return `/v1/${backend}?help=1`;
// },
name: attr('string', {
@@ -55,15 +54,6 @@ export default DS.Model.extend({
subText:
'Vault provides two types of transformations: Format Preserving Encryption (FPE) is reversible, while Masking is not.',
}),
- template: attr('stringArray', {
- label: 'Template', // TODO: make this required for making a transformation
- subLabel: 'Template Name',
- subText:
- 'Templates allow Vault to determine what and how to capture the value to be transformed. Type to use an existing template or create a new one.',
- editType: 'searchSelect',
- fallbackComponent: 'string-list',
- models: ['transform/template'],
- }),
tweak_source: attr('string', {
defaultValue: 'supplied',
label: 'Tweak source',
@@ -71,35 +61,42 @@ export default DS.Model.extend({
subText: `A tweak value is used when performing FPE transformations. This can be supplied, generated, or internal.`, // TODO: I do not include the link here. Need to figure out the best way to approach this.
}),
masking_character: attr('string', {
+ defaultValue: '*',
label: 'Masking character',
subText: 'Specify which character you’d like to mask your data.',
}),
- allowed_roles: attr('stringArray', {
+ template: attr('string', {
+ editType: 'searchSelect',
+ fallbackComponent: 'string-list',
+ label: 'Template', // TODO: make this required for making a transformation
+ models: ['transform/template'],
+ subLabel: 'Template Name',
+ subText:
+ 'Templates allow Vault to determine what and how to capture the value to be transformed. Type to use an existing template or create a new one.',
+ }),
+ templates: attr('array'), // TODO: remove once BE changes the returned property to a singular template on the GET request.
+ allowed_roles: attr('string', {
label: 'Allowed roles',
editType: 'searchSelect',
fallbackComponent: 'string-list',
models: ['transform/role'],
subText: 'Search for an existing role, type a new role to create it, or use a wildcard (*).',
}),
- transformAttrs: computed(function() {
+ transformAttrs: computed('type', function() {
// TODO: group them into sections/groups. Right now, we don't different between required and not required as we do by hiding options.
// will default to design mocks on how to handle as it will likely be a different pattern using client-side validation, which we have not done before
- return ['name', 'type', 'template', 'tweak_source', 'masking_characters', 'allowed_roles'];
+ if (this.type === 'masking') {
+ return ['name', 'type', 'masking_character', 'template', 'templates', 'allowed_roles'];
+ }
+ return ['name', 'type', 'tweak_source', 'template', 'templates', 'allowed_roles'];
}),
transformFieldAttrs: computed('transformAttrs', function() {
return expandAttributeMeta(this, this.get('transformAttrs'));
}),
- updatePath: lazyCapabilities(apiPath`${'backend'}/transforms/${'id'}`, 'backend', 'id'),
- canDelete: alias('updatePath.canDelete'),
- canEdit: alias('updatePath.canUpdate'),
- canRead: alias('updatePath.canRead'),
-
- generatePath: lazyCapabilities(apiPath`${'backend'}/creds/${'id'}`, 'backend', 'id'),
- canGenerate: alias('generatePath.canUpdate'),
-
- signPath: lazyCapabilities(apiPath`${'backend'}/sign/${'id'}`, 'backend', 'id'),
- canSign: alias('signPath.canUpdate'),
+ // zeroAddressPath: lazyCapabilities(apiPath`${'backend'}/config/zeroaddress`, 'backend'),
+ // canEditZeroAddress: alias('zeroAddressPath.canUpdate'),
+});
- zeroAddressPath: lazyCapabilities(apiPath`${'backend'}/config/zeroaddress`, 'backend'),
- canEditZeroAddress: alias('zeroAddressPath.canUpdate'),
+export default attachCapabilities(Model, {
+ updatePath: apiPath`transform/transformation/${'id'}`,
});
diff --git a/ui/app/serializers/transform.js b/ui/app/serializers/transform.js
new file mode 100644
index 000000000000..a466cc4d5df9
--- /dev/null
+++ b/ui/app/serializers/transform.js
@@ -0,0 +1,11 @@
+import ApplicationSerializer from './application';
+
+export default ApplicationSerializer.extend({
+ normalizeResponse(store, primaryModelClass, payload, id, requestType) {
+ if (payload.data.masking_character) {
+ payload.data.masking_character = String.fromCharCode(payload.data.masking_character);
+ }
+ // TODO: the BE is working on a ticket to amend these response, so revisit.
+ return this._super(store, primaryModelClass, payload, id, requestType);
+ },
+});
diff --git a/ui/app/styles/components/transform-edit.scss b/ui/app/styles/components/transform-edit.scss
new file mode 100644
index 000000000000..57400100420a
--- /dev/null
+++ b/ui/app/styles/components/transform-edit.scss
@@ -0,0 +1,8 @@
+.copy-text {
+ background: $ui-gray-010;
+
+ & > code {
+ color: $ui-gray-800;
+ padding: 14px;
+ }
+}
diff --git a/ui/app/styles/core.scss b/ui/app/styles/core.scss
index 62d76be84129..2e684cfd7df8 100644
--- a/ui/app/styles/core.scss
+++ b/ui/app/styles/core.scss
@@ -103,6 +103,7 @@
@import './components/token-expire-warning';
@import './components/toolbar';
@import './components/tool-tip';
+@import './components/transform-edit.scss';
@import './components/transit-card';
@import './components/ttl-picker2';
@import './components/unseal-warning';
diff --git a/ui/app/styles/core/forms.scss b/ui/app/styles/core/forms.scss
index 113576c374da..074ae263c9b9 100644
--- a/ui/app/styles/core/forms.scss
+++ b/ui/app/styles/core/forms.scss
@@ -21,7 +21,7 @@ label {
.b-checkbox .is-label {
color: $grey-darker;
display: inline-block;
- font-size: $size-small;
+ font-size: $body-size;
font-weight: $font-weight-bold;
&:not(:last-child) {
@@ -73,6 +73,7 @@ label {
.sub-text {
color: $grey;
margin-bottom: 0.25rem;
+ font-size: $size-8;
}
.input,
.textarea,
diff --git a/ui/app/styles/core/helpers.scss b/ui/app/styles/core/helpers.scss
index ecc7bd6ad1da..a9c76e02f2e9 100644
--- a/ui/app/styles/core/helpers.scss
+++ b/ui/app/styles/core/helpers.scss
@@ -168,6 +168,10 @@
.has-top-margin-xl {
margin-top: $spacing-xl;
}
+.has-border-bottom-light {
+ border-radius: 0;
+ border-bottom: 1px solid $grey-light;
+}
.has-border-danger {
border: 1px solid $danger;
}
diff --git a/ui/app/templates/components/transform-edit-form.hbs b/ui/app/templates/components/transform-edit-form.hbs
index f693b79aa7d9..a35e16c68245 100644
--- a/ui/app/templates/components/transform-edit-form.hbs
+++ b/ui/app/templates/components/transform-edit-form.hbs
@@ -10,7 +10,6 @@
@model={{model}}
/>
{{/each}}
-
vault write transform/encode/payments value=<enter your value here>
+ vault write transform/decode/payments value=<enter your value here>
+ {{model.id}}
+ Transformation {{model.id}}
{{/if}}
@@ -24,55 +24,39 @@
{{#if (eq mode "show")}}