diff --git a/addons/api/addon/generated/models/credential-library.js b/addons/api/addon/generated/models/credential-library.js index 3d8ba617e..9e8d9c0d1 100644 --- a/addons/api/addon/generated/models/credential-library.js +++ b/addons/api/addon/generated/models/credential-library.js @@ -81,9 +81,10 @@ export default class GeneratedCredentialLibraryModel extends BaseModel { }) credential_type; - @attr('object-as-array', { + @attr('object', { for: 'vault-generic', description: 'It indicates the credential mapping overrides.', + emptyObjectIfMissing: true, }) credential_mapping_overrides; diff --git a/addons/api/addon/serializers/credential-library.js b/addons/api/addon/serializers/credential-library.js index 5e2186eb7..13e155c83 100644 --- a/addons/api/addon/serializers/credential-library.js +++ b/addons/api/addon/serializers/credential-library.js @@ -68,7 +68,9 @@ export default class CredentialLibrarySerializer extends ApplicationSerializer { */ handleCredentialMappingOverrides(serialized, isNew) { const { credential_type, credential_mapping_overrides } = serialized; - + if (Object.keys(credential_mapping_overrides).length === 0) { + serialized.credential_mapping_overrides = null; + } // API expects to send null to fields if it is undefined or deleted if (credential_mapping_overrides && !isNew) { serialized.credential_mapping_overrides = options.mapping_overrides[ diff --git a/addons/api/tests/unit/serializers/credential-library-test.js b/addons/api/tests/unit/serializers/credential-library-test.js index 817ecb42c..cb90605d6 100644 --- a/addons/api/tests/unit/serializers/credential-library-test.js +++ b/addons/api/tests/unit/serializers/credential-library-test.js @@ -25,9 +25,7 @@ module('Unit | Serializer | credential library', function (hooks) { http_method: 'GET', version: 1, credential_type: 'ssh_private_key', - credential_mapping_overrides: [ - { key: 'username_attribute', value: 'user' }, - ], + credential_mapping_overrides: { username_attribute: 'user' }, }); const snapshot = record._createSnapshot(); const serializedRecord = serializer.serialize(snapshot); @@ -64,9 +62,7 @@ module('Unit | Serializer | credential library', function (hooks) { http_method: 'GET', version: 1, credential_type: 'ssh_private_key', - credential_mapping_overrides: [ - { key: 'private_key_attribute', value: 'test' }, - ], + credential_mapping_overrides: { private_key_attribute: 'test' }, }, }, }); diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml index c73fe5d82..9b91d20b3 100644 --- a/addons/core/translations/resources/en-us.yaml +++ b/addons/core/translations/resources/en-us.yaml @@ -913,11 +913,12 @@ credential-library: ssh_private_key: SSH Private Key username_password: Username & Password username_password_domain: Username, Password & Domain - username_attribute: Username - password_attribute: Password - private_key_passphrase_attribute: Private Key Passphrase - private_key_attribute: Private Key - domain_attribute: Domain + password: Password + username_attribute: username_attribute + password_attribute: password_attribute + private_key_passphrase_attribute: private_key_passphrase_attribute + private_key_attribute: private_key_attribute + domain_attribute: domain_attribute actions: create: New Credential Library delete: Delete Credential Library diff --git a/e2e-tests/admin/pages/credential-stores.js b/e2e-tests/admin/pages/credential-stores.js index f11c88a6f..716021ceb 100644 --- a/e2e-tests/admin/pages/credential-stores.js +++ b/e2e-tests/admin/pages/credential-stores.js @@ -308,11 +308,9 @@ export class CredentialStoresPage extends BaseResourcePage { await this.page.getByRole('link', { name: 'Credential Libraries' }).click(); await this.page.getByRole('link', { name: 'New', exact: true }).click(); await this.page - .getByLabel('Name (Optional)', { exact: true }) + .getByLabel('Name', { exact: true }) .fill(credentialLibraryName); - await this.page - .getByLabel('Description (Optional)') - .fill('This is an automated test'); + await this.page.getByLabel('Description').fill('This is an automated test'); await this.page .getByRole('group', { name: 'Type' }) .getByLabel('Generic Secrets') @@ -345,11 +343,9 @@ export class CredentialStoresPage extends BaseResourcePage { await this.page.getByRole('link', { name: 'New', exact: true }).click(); await this.page - .getByLabel('Name (Optional)', { exact: true }) + .getByLabel('Name', { exact: true }) .fill(credentialLibraryName); - await this.page - .getByLabel('Description (Optional)') - .fill('This is an automated test'); + await this.page.getByLabel('Description').fill('This is an automated test'); await this.page .getByRole('group', { name: 'Type' }) .getByLabel('SSH Certificates') diff --git a/e2e-tests/admin/tests/credential-store-vault.spec.js b/e2e-tests/admin/tests/credential-store-vault.spec.js index fa148d474..3f4c7f413 100644 --- a/e2e-tests/admin/tests/credential-store-vault.spec.js +++ b/e2e-tests/admin/tests/credential-store-vault.spec.js @@ -99,11 +99,9 @@ test( await page.getByRole('link', { name: 'Credential Libraries' }).click(); await page.getByRole('link', { name: 'New', exact: true }).click(); await page - .getByLabel('Name (Optional)', { exact: true }) + .getByLabel('Name', { exact: true }) .fill(credentialLibraryName); - await page - .getByLabel('Description (Optional)') - .fill('This is an automated test'); + await page.getByLabel('Description').fill('This is an automated test'); await page .getByLabel('Vault Path') .fill(`${secretsPath}/data/${secretName}`); diff --git a/ui/admin/app/components/form/credential-library/mapping-overrides/index.hbs b/ui/admin/app/components/form/credential-library/mapping-overrides/index.hbs index 894013d87..d22d2697e 100644 --- a/ui/admin/app/components/form/credential-library/mapping-overrides/index.hbs +++ b/ui/admin/app/components/form/credential-library/mapping-overrides/index.hbs @@ -3,49 +3,36 @@ SPDX-License-Identifier: BUSL-1.1 }} - - <:fieldset as |F|> - - {{t - 'resources.credential-library.form.credential_mapping_overrides.label' - }} - - - {{t - 'resources.credential-library.form.credential_mapping_overrides.help' - }} - - - {{#if @model.errors.credential_mapping_overrides}} - - {{#each @model.errors.credential_mapping_overrides as |error|}} - {{error.message}} - {{/each}} - - {{/if}} - - - <:field as |F|> - - <:newKey as |N|> - - - <:key as |K|> - - - <:value as |V|> - - - - - \ No newline at end of file + + {{t + 'resources.credential-library.form.credential_mapping_overrides.label' + }} + {{t + 'resources.credential-library.form.credential_mapping_overrides.help' + }} + + {{#each this.mappingOverrides as |option|}} + + {{t + (concat 'resources.credential-library.titles.' option) + }} + + {{/each}} + + {{#if @model.errors.credential_mapping_overrides}} + + {{#each @model.errors.credential_mapping_overrides as |error|}} + {{error.message}} + {{/each}} + + {{/if}} + \ No newline at end of file diff --git a/ui/admin/app/components/form/credential-library/mapping-overrides/index.js b/ui/admin/app/components/form/credential-library/mapping-overrides/index.js index 9d50d724a..cd082393b 100644 --- a/ui/admin/app/components/form/credential-library/mapping-overrides/index.js +++ b/ui/admin/app/components/form/credential-library/mapping-overrides/index.js @@ -5,43 +5,11 @@ import Component from '@glimmer/component'; import { options } from 'api/models/credential-library'; -import { action } from '@ember/object'; export default class FormCredentialLibraryMappingOverridesComponent extends Component { + // =attributes + get mappingOverrides() { return options.mapping_overrides[this.args.model.credential_type]; } - - get allowedEntries() { - return this.mappingOverrides.length; - } - - /** - * Prevents users from selecting duplicate keys from the select list if the arg is set to true - * @type {array} - */ - get selectOptions() { - const previouslySelectedKeys = - this.args.model.credential_mapping_overrides || []; - if (previouslySelectedKeys.length) { - return this.mappingOverrides.filter((key) => - previouslySelectedKeys.every((obj) => obj.key !== key), - ); - } else { - return this.mappingOverrides; - } - } - - /** - * Determines if we need to show an empty row to the users to enter more key/value pairs based on removeDuplicates arg, - * by default it is true - * @type {object} - */ - @action - showNewRow() { - return ( - this.args.model.credential_mapping_overrides?.length !== - this.allowedEntries - ); - } } diff --git a/ui/admin/app/components/form/credential-library/radio/index.hbs b/ui/admin/app/components/form/credential-library/radio/index.hbs index e2bc8fd96..fa209f079 100644 --- a/ui/admin/app/components/form/credential-library/radio/index.hbs +++ b/ui/admin/app/components/form/credential-library/radio/index.hbs @@ -5,6 +5,7 @@ diff --git a/ui/admin/app/components/form/credential-library/vault-generic/index.hbs b/ui/admin/app/components/form/credential-library/vault-generic/index.hbs index f4b61eb27..aaa1725e1 100644 --- a/ui/admin/app/components/form/credential-library/vault-generic/index.hbs +++ b/ui/admin/app/components/form/credential-library/vault-generic/index.hbs @@ -14,7 +14,6 @@ name='name' @value={{@model.name}} @isInvalid={{@model.errors.name}} - @isOptional={{true}} disabled={{form.disabled}} {{on 'input' (set-from-event @model 'name')}} as |F| @@ -36,7 +35,6 @@ name='description' @value={{@model.description}} @isInvalid={{@model.errors.description}} - @isOptional={{true}} disabled={{form.disabled}} as |F| > @@ -70,7 +68,6 @@ {{/if}} - {{else}} + {{else if @model.credential_type}} this.server.schema.credentialLibraries.all().models.length; - getUsernamePasswordDomainCredentialLibraryCount = () => { - return this.server.schema.credentialLibraries.where({ - credentialType: TYPE_CREDENTIAL_USERNAME_PASSWORD_DOMAIN, - }).length; + getTypeCredentialLibraryCount = (credentialType) => { + return this.server.schema.credentialLibraries.where({ credentialType }) + .length; }; featuresService = this.owner.lookup('service:features'); }); @@ -100,102 +100,68 @@ module('Acceptance | credential-libraries | create', function (hooks) { assert.strictEqual(currentURL(), urls.credentialLibrary); }); - test('can create a new credential library of type vault generic', async function (assert) { - setRunOptions({ - rules: { - 'color-contrast': { - // [ember-a11y-ignore]: axe rule "color-contrast" automatically ignored on 2025-08-01 - enabled: false, + test.each( + 'can create a new credential library with credential type for vault generic', + options.credential_types, + async function (assert, type) { + setRunOptions({ + rules: { + 'color-contrast': { + // [ember-a11y-ignore]: axe rule "color-contrast" automatically ignored on 2025-08-26 + enabled: false, + }, }, - }, - }); + }); - const count = getCredentialLibraryCount(); - await visit(urls.newCredentialLibrary); + const credentialLibraryCount = getCredentialLibraryCount(); + const typeCredentialLibraryCount = getTypeCredentialLibraryCount(type); + await visit(urls.newCredentialLibrary); - await fillIn(commonSelectors.FIELD_NAME, commonSelectors.FIELD_NAME_VALUE); - await select( - selectors.FIELD_CRED_TYPE, - selectors.FIELD_CRED_TYPE_SSH_VALUE, - ); - await select( - selectors.FIELD_CRED_MAP_OVERRIDES_SELECT, - selectors.FIELD_CRED_MAP_OVERRIDES_SELECT_SSH_VALUE, - ); - await fillIn(selectors.FIELD_CRED_MAP_OVERRIDES_INPUT, 'key'); - await click(selectors.FIELD_CRED_MAP_OVERRIDES_BTN); - await click(commonSelectors.SAVE_BTN); + await fillIn( + selectors.FIELD_VAULT_PATH, + selectors.FIELD_VAULT_PATH_VALUE, + ); + await fillIn( + commonSelectors.FIELD_NAME, + commonSelectors.FIELD_NAME_VALUE, + ); + await select(selectors.FIELD_CRED_TYPE, type); - assert.strictEqual(getCredentialLibraryCount(), count + 1); - const credentialLibrary = this.server.schema.credentialLibraries.findBy({ - name: commonSelectors.FIELD_NAME_VALUE, - }); - assert.strictEqual( - credentialLibrary.name, - commonSelectors.FIELD_NAME_VALUE, - ); - assert.strictEqual( - credentialLibrary.credentialType, - selectors.FIELD_CRED_TYPE_SSH_VALUE, - ); - assert.deepEqual(credentialLibrary.credentialMappingOverrides, { - private_key_attribute: 'key', - }); - }); + const credentialMappingOverrides = {}; + options.mapping_overrides[type].forEach(async (overrideField) => { + const randName = faker.word.words(); + credentialMappingOverrides[overrideField] = randName; + await fillIn( + selectors.FIELD_CRED_MAP_OVERRIDES(overrideField), + randName, + ); + }); + await click(commonSelectors.SAVE_BTN); - test('can create a new credential library with username, password and domain type for vault generic', async function (assert) { - setRunOptions({ - rules: { - 'color-contrast': { - // [ember-a11y-ignore]: axe rule "color-contrast" automatically ignored on 2025-08-26 - enabled: false, - }, - }, - }); + assert.strictEqual( + getCredentialLibraryCount(), + credentialLibraryCount + 1, + ); + assert.strictEqual( + getTypeCredentialLibraryCount(), + typeCredentialLibraryCount + 1, + ); - const credentialLibraryCount = getCredentialLibraryCount(); - const usernamePasswordDomainCredentialLibraryCount = - getUsernamePasswordDomainCredentialLibraryCount(); - await visit(urls.newCredentialLibrary); + const credentialLibrary = this.server.schema.credentialLibraries.findBy({ + credentialType: type, + }); - await fillIn(selectors.FIELD_VAULT_PATH, selectors.FIELD_VAULT_PATH_VALUE); - await fillIn(commonSelectors.FIELD_NAME, commonSelectors.FIELD_NAME_VALUE); - await select( - selectors.FIELD_CRED_TYPE, - selectors.FIELD_CRED_TYPE_UPD_VALUE, - ); - - await select( - selectors.FIELD_CRED_MAP_OVERRIDES_SELECT, - selectors.FIELD_CRED_MAP_OVERRIDES_SELECT_DOMAIN_VALUE, - ); - await fillIn(selectors.FIELD_CRED_MAP_OVERRIDES_INPUT, 'domain'); - - await click(selectors.FIELD_CRED_MAP_OVERRIDES_BTN); - await click(commonSelectors.SAVE_BTN); - - assert.strictEqual(getCredentialLibraryCount(), credentialLibraryCount + 1); - assert.strictEqual( - getUsernamePasswordDomainCredentialLibraryCount(), - usernamePasswordDomainCredentialLibraryCount + 1, - ); - - const credentialLibrary = this.server.schema.credentialLibraries.findBy({ - credentialType: TYPE_CREDENTIAL_USERNAME_PASSWORD_DOMAIN, - }); - - assert.strictEqual( - credentialLibrary.name, - commonSelectors.FIELD_NAME_VALUE, - ); - assert.strictEqual( - credentialLibrary.credentialType, - selectors.FIELD_CRED_TYPE_UPD_VALUE, - ); - assert.deepEqual(credentialLibrary.credentialMappingOverrides, { - domain_attribute: 'domain', - }); - }); + assert.strictEqual( + credentialLibrary.name, + commonSelectors.FIELD_NAME_VALUE, + ); + assert.strictEqual(credentialLibrary.credentialType, type); + assert.deepEqual( + credentialLibrary.credentialMappingOverrides, + credentialMappingOverrides, + ); + }, + ); test('can create a new credential library of type vault ssh cert', async function (assert) { setRunOptions({ diff --git a/ui/admin/tests/acceptance/credential-library/selectors.js b/ui/admin/tests/acceptance/credential-library/selectors.js index d66b0891d..8b208703e 100644 --- a/ui/admin/tests/acceptance/credential-library/selectors.js +++ b/ui/admin/tests/acceptance/credential-library/selectors.js @@ -26,15 +26,7 @@ export const FIELD_TTL_VALUE = 'ttl'; export const FIELD_KEY_ID = '[name=key_id]'; export const FIELD_KEY_ID_VALUE = 'key_id'; -export const FIELD_CRED_MAP_OVERRIDES_SELECT = - '[name="credential_mapping_overrides"] select'; -export const FIELD_CRED_MAP_OVERRIDES_SELECT_SSH_VALUE = - 'private_key_attribute'; -export const FIELD_CRED_MAP_OVERRIDES_SELECT_DOMAIN_VALUE = 'domain_attribute'; -export const FIELD_CRED_MAP_OVERRIDES_INPUT = - '[name="credential_mapping_overrides"] input'; -export const FIELD_CRED_MAP_OVERRIDES_BTN = - '[name="credential_mapping_overrides"] button'; +export const FIELD_CRED_MAP_OVERRIDES = (field) => `[name=${field}]`; export const TYPE_VAULT_SSH_CERT = '[value="vault-ssh-certificate"]'; export const TYPE_VAULT_LDAP = '[value="vault-ldap"]'; diff --git a/ui/admin/tests/acceptance/credential-library/update-test.js b/ui/admin/tests/acceptance/credential-library/update-test.js index 8366c7939..1ea602eaf 100644 --- a/ui/admin/tests/acceptance/credential-library/update-test.js +++ b/ui/admin/tests/acceptance/credential-library/update-test.js @@ -4,19 +4,20 @@ */ import { module, test } from 'qunit'; -import { visit, click, fillIn, currentURL, select } from '@ember/test-helpers'; +import { visit, click, fillIn, currentURL } from '@ember/test-helpers'; import { setupApplicationTest } from 'admin/tests/helpers'; import { setupSqlite } from 'api/test-support/helpers/sqlite'; import { Response } from 'miragejs'; +import { faker } from '@faker-js/faker'; +import * as selectors from './selectors'; +import * as commonSelectors from 'admin/tests/helpers/selectors'; +import { setRunOptions } from 'ember-a11y-testing/test-support'; import { TYPE_CREDENTIAL_LIBRARY_VAULT_SSH_CERTIFICATE, TYPE_CREDENTIAL_LIBRARY_VAULT_GENERIC, TYPE_CREDENTIAL_LIBRARY_VAULT_LDAP, } from 'api/models/credential-library'; -import * as selectors from './selectors'; -import * as commonSelectors from 'admin/tests/helpers/selectors'; -import { setRunOptions } from 'ember-a11y-testing/test-support'; -import { TYPE_CREDENTIAL_USERNAME_PASSWORD_DOMAIN } from 'api/models/credential'; +import { options } from 'api/models/credential-library'; module('Acceptance | credential-libraries | update', function (hooks) { setupApplicationTest(hooks); @@ -57,17 +58,9 @@ module('Acceptance | credential-libraries | update', function (hooks) { }); instances.credentialLibrary = this.server.create('credential-library', { scope: instances.scopes.project, + type: TYPE_CREDENTIAL_LIBRARY_VAULT_GENERIC, credentialStore: instances.credentialStore, }); - instances.usernamePasswordDomainCredentialLibrary = this.server.create( - 'credential-library', - { - scope: instances.scopes.project, - credentialStore: instances.credentialStore, - type: TYPE_CREDENTIAL_LIBRARY_VAULT_GENERIC, - credential_type: TYPE_CREDENTIAL_USERNAME_PASSWORD_DOMAIN, - }, - ); instances.vaultLDAPCredentialLibrary = this.server.create( 'credential-library', { @@ -86,7 +79,6 @@ module('Acceptance | credential-libraries | update', function (hooks) { urls.credentialLibrary = `${urls.credentialLibraries}/${instances.credentialLibrary.id}`; urls.newCredentialLibrary = `${urls.credentialLibraries}/new`; urls.unknownCredentialLibrary = `${urls.credentialLibraries}/foo`; - urls.usernamePasswordDomainCredentialLibrary = `${urls.credentialLibraries}/${instances.usernamePasswordDomainCredentialLibrary.id}`; urls.vaultLDAPCredentialLibrary = `${urls.credentialLibraries}/${instances.vaultLDAPCredentialLibrary.id}`; }); @@ -126,100 +118,67 @@ module('Acceptance | credential-libraries | update', function (hooks) { .hasValue(instances.credentialLibrary.name); }); - test('can update a vault generic credential library and save changes', async function (assert) { - setRunOptions({ - rules: { - 'color-contrast': { - // [ember-a11y-ignore]: axe rule "color-contrast" automatically ignored on 2025-08-01 - enabled: false, + test.each( + 'can update a vault generic credential library with credential type and save changes', + options.credential_types, + async function (assert, type) { + setRunOptions({ + rules: { + 'color-contrast': { + // [ember-a11y-ignore]: axe rule "color-contrast" automatically ignored on 2025-08-26 + enabled: false, + }, }, - }, - }); + }); + instances.credentialLibrary.update({ credentialType: type }); + await visit(urls.credentialLibraries); - await visit(urls.credentialLibrary); + await click(commonSelectors.HREF(urls.credentialLibrary)); + await click(commonSelectors.EDIT_BTN); + await fillIn( + commonSelectors.FIELD_NAME, + commonSelectors.FIELD_NAME_VALUE, + ); + await fillIn( + commonSelectors.FIELD_DESCRIPTION, + commonSelectors.FIELD_DESCRIPTION_VALUE, + ); + await fillIn( + selectors.FIELD_VAULT_PATH, + selectors.FIELD_VAULT_PATH_VALUE, + ); + const credentialMappingOverrides = {}; + options.mapping_overrides[type].forEach(async (overrideField) => { + const randName = faker.word.words(); + credentialMappingOverrides[overrideField] = randName; + await fillIn( + selectors.FIELD_CRED_MAP_OVERRIDES(overrideField), + randName, + ); + }); + await click(commonSelectors.SAVE_BTN); - await click(commonSelectors.EDIT_BTN); - await fillIn(commonSelectors.FIELD_NAME, commonSelectors.FIELD_NAME_VALUE); - await fillIn( - commonSelectors.FIELD_DESCRIPTION, - commonSelectors.FIELD_DESCRIPTION_VALUE, - ); - await fillIn(selectors.FIELD_VAULT_PATH, selectors.FIELD_VAULT_PATH_VALUE); - await select( - selectors.FIELD_CRED_MAP_OVERRIDES_SELECT, - selectors.FIELD_CRED_MAP_OVERRIDES_SELECT_SSH_VALUE, - ); - await fillIn(selectors.FIELD_CRED_MAP_OVERRIDES_INPUT, 'key'); - await click(selectors.FIELD_CRED_MAP_OVERRIDES_BTN); - await click(commonSelectors.SAVE_BTN); - - const credentialLibrary = this.server.schema.credentialLibraries.findBy({ - name: commonSelectors.FIELD_NAME_VALUE, - }); - assert.strictEqual( - credentialLibrary.name, - commonSelectors.FIELD_NAME_VALUE, - ); - assert.strictEqual( - credentialLibrary.description, - commonSelectors.FIELD_DESCRIPTION_VALUE, - ); - assert.strictEqual( - credentialLibrary.attributes.path, - selectors.FIELD_VAULT_PATH_VALUE, - ); - assert.deepEqual(credentialLibrary.credentialMappingOverrides, { - private_key_attribute: 'key', - }); - }); - - test('can update a vault generic credential library of username, password and domain type and save changes', async function (assert) { - setRunOptions({ - rules: { - 'color-contrast': { - // [ember-a11y-ignore]: axe rule "color-contrast" automatically ignored on 2025-08-26 - enabled: false, - }, - }, - }); - - await visit(urls.usernamePasswordDomainCredentialLibrary); - - await click(commonSelectors.EDIT_BTN); - await fillIn(commonSelectors.FIELD_NAME, commonSelectors.FIELD_NAME_VALUE); - await fillIn( - commonSelectors.FIELD_DESCRIPTION, - commonSelectors.FIELD_DESCRIPTION_VALUE, - ); - await fillIn(selectors.FIELD_VAULT_PATH, selectors.FIELD_VAULT_PATH_VALUE); - await select( - selectors.FIELD_CRED_MAP_OVERRIDES_SELECT, - selectors.FIELD_CRED_MAP_OVERRIDES_SELECT_DOMAIN_VALUE, - ); - await fillIn(selectors.FIELD_CRED_MAP_OVERRIDES_INPUT, 'domain'); - - await click(selectors.FIELD_CRED_MAP_OVERRIDES_BTN); - await click(commonSelectors.SAVE_BTN); - - const credentialLibrary = this.server.schema.credentialLibraries.findBy({ - credentialType: TYPE_CREDENTIAL_USERNAME_PASSWORD_DOMAIN, - }); - assert.strictEqual( - credentialLibrary.name, - commonSelectors.FIELD_NAME_VALUE, - ); - assert.strictEqual( - credentialLibrary.description, - commonSelectors.FIELD_DESCRIPTION_VALUE, - ); - assert.strictEqual( - credentialLibrary.attributes.path, - selectors.FIELD_VAULT_PATH_VALUE, - ); - assert.deepEqual(credentialLibrary.credentialMappingOverrides, { - domain_attribute: 'domain', - }); - }); + const credentialLibrary = this.server.schema.credentialLibraries.findBy({ + credentialType: type, + }); + assert.strictEqual( + credentialLibrary.name, + commonSelectors.FIELD_NAME_VALUE, + ); + assert.strictEqual( + credentialLibrary.description, + commonSelectors.FIELD_DESCRIPTION_VALUE, + ); + assert.strictEqual( + credentialLibrary.attributes.path, + selectors.FIELD_VAULT_PATH_VALUE, + ); + assert.deepEqual( + credentialLibrary.credentialMappingOverrides, + credentialMappingOverrides, + ); + }, + ); test('saving an existing credential library with invalid fields displays error messages', async function (assert) { setRunOptions({ diff --git a/ui/desktop/app/styles/app.scss b/ui/desktop/app/styles/app.scss index e53d43c10..03eb12f01 100644 --- a/ui/desktop/app/styles/app.scss +++ b/ui/desktop/app/styles/app.scss @@ -331,6 +331,8 @@ .credential-header { padding: 1.5rem; width: 33%; + display: flex; + flex-direction: column; } .credential-secret {