diff --git a/ui/admin/app/components/form/auth-method/oidc/index.hbs b/ui/admin/app/components/form/auth-method/oidc/index.hbs
index 63f2b5ada..45150cfb1 100644
--- a/ui/admin/app/components/form/auth-method/oidc/index.hbs
+++ b/ui/admin/app/components/form/auth-method/oidc/index.hbs
@@ -146,113 +146,109 @@
{{/unless}}
- {{! Signing Algorithms }}
-
- <:fieldset as |F|>
-
- {{t 'form.signing_algorithms.label'}}
-
-
- {{t 'form.signing_algorithms.help'}}
-
-
- {{#if @model.errors.signing_algorithms}}
-
- {{#each @model.errors.signing_algorithms as |error|}}
- {{error.message}}
- {{/each}}
-
- {{/if}}
-
-
- <:field as |F|>
-
-
-
-
- {{! Allowed Audiences }}
-
- <:fieldset as |F|>
-
- {{t 'form.allowed_audiences.label'}}
-
-
- {{t 'form.allowed_audiences.help'}}
-
-
- {{#if @model.errors.allowed_audiences}}
-
- {{#each @model.errors.allowed_audiences as |error|}}
- {{error.message}}
+ <:row as |R|>
+
+
+
+ {{#each this.signingAlgorithms as |algorithm|}}
+
{{/each}}
-
+
+
+ {{#if R.canDelete}}
+
{{/if}}
-
+
+
- <:field as |F|>
-
-
-
-
+ {{! Allowed audiences }}
+
+ <:row as |R|>
+
+
+
+ {{#if R.canDelete}}
+
+ {{/if}}
+
+
{{! Claims Scopes }}
-
-
- <:fieldset as |F|>
-
- {{t 'form.claims_scopes.label'}}
-
-
- {{t 'form.claims_scopes.help'}}
-
-
- {{#if @model.errors.claims_scopes}}
-
- {{#each @model.errors.claims_scopes as |error|}}
- {{error.message}}
- {{/each}}
-
+ <:row as |R|>
+
+
+
+ {{#if R.canDelete}}
+
{{/if}}
-
-
- <:field as |F|>
-
-
-
-
+
+
{{! Account Claim Maps }}
{{! Certificates }}
-
- <:fieldset as |F|>
-
- {{t 'form.idp_ca_certs.label'}}
-
-
- {{t 'form.idp_ca_certs.help'}}
-
-
- {{#if @model.errors.idp_ca_certs}}
-
- {{#each @model.errors.idp_ca_certs as |error|}}
- {{error.message}}
- {{/each}}
-
+ <:row as |R|>
+
+
+
+ {{#if R.canDelete}}
+
{{/if}}
-
-
- <:field as |F|>
-
-
-
-
+
+
({ value: '' });
+
+ // For fields with key and value properties
+ createEmptyKeyValue = () => ({ key: '', value: '' });
// =attributes
/**
@@ -55,45 +60,6 @@ export default class FormAuthMethodOidcComponent extends Component {
//actions
- /**
- * Adds a new empty row to account claim maps
- */
- @action
- addAccountClaimMap() {
- this.args.model.account_claim_maps = [
- ...this.args.model.account_claim_maps,
- { key: '', value: '' },
- ];
- }
-
- /**
- * Removes a row from account claim maps
- * @param {Object} rowData - The row to remove
- */
- @action
- removeAccountClaimMap(rowData) {
- let rows = this.args.model.account_claim_maps.filter(
- (item) => item !== rowData,
- );
-
- // Ensure at least one empty row exists for editing
- if (rows.length === 0) {
- rows = [{ key: '', value: '' }];
- }
- this.args.model.account_claim_maps = rows;
- }
-
- /**
- * Updates the account claim maps in the model
- */
- @action
- updateAccountClaimMap(rowData, property, { target: { value } }) {
- rowData[property] = value;
- this.args.model.account_claim_maps = [
- ...this.args.model.account_claim_maps,
- ];
- }
-
/**
* @param {string} value
*/
@@ -128,4 +94,34 @@ export default class FormAuthMethodOidcComponent extends Component {
this.args.model.prompts = [...removeSelection];
}
}
+
+ /**
+ * Adds a new empty row to account claim maps
+ */
+ @action
+ addRow(field, emptyRow) {
+ this.args.model[field] = [...this.args.model[field], emptyRow()];
+ }
+
+ /**
+ * Removes a row from account claim maps
+ */
+ @action
+ removeRow(field, emptyRow, rowData) {
+ let rows = this.args.model[field].filter((item) => item !== rowData);
+ // Ensure at least one empty row exists for editing
+ if (rows.length === 0) {
+ rows = [emptyRow()];
+ }
+ this.args.model[field] = rows;
+ }
+
+ /**
+ * Updates the account claim maps in the model
+ */
+ @action
+ updateRow(field, rowData, property, { target: { value } }) {
+ rowData[property] = value;
+ this.args.model[field] = [...this.args.model[field]];
+ }
}
diff --git a/ui/admin/app/controllers/scopes/scope/auth-methods/index.js b/ui/admin/app/controllers/scopes/scope/auth-methods/index.js
index f41d059b5..8b287d3a4 100644
--- a/ui/admin/app/controllers/scopes/scope/auth-methods/index.js
+++ b/ui/admin/app/controllers/scopes/scope/auth-methods/index.js
@@ -153,6 +153,26 @@ export default class ScopesScopeAuthMethodsIndexController extends Controller {
(item) => item.key?.trim(),
);
}
+ if (authMethod.claims_scopes) {
+ authMethod.claims_scopes = authMethod.claims_scopes.filter((item) =>
+ item.value?.trim(),
+ );
+ }
+ if (authMethod.allowed_audiences) {
+ authMethod.allowed_audiences = authMethod.allowed_audiences.filter(
+ (item) => item.value?.trim(),
+ );
+ }
+ if (authMethod.signing_algorithms) {
+ authMethod.signing_algorithms = authMethod.signing_algorithms.filter(
+ (item) => item.value?.trim(),
+ );
+ }
+ if (authMethod.idp_ca_certs) {
+ authMethod.idp_ca_certs = authMethod.idp_ca_certs.filter((item) =>
+ item.value?.trim(),
+ );
+ }
await authMethod.save();
if (this.abilities.can('read model', authMethod)) {
await this.router.transitionTo(
@@ -296,19 +316,32 @@ export default class ScopesScopeAuthMethodsIndexController extends Controller {
edit(authMethod) {
if (authMethod.claims_scopes) {
authMethod.claims_scopes = structuredClone(authMethod.claims_scopes);
+ // Ensure at least one empty row exists for editing
+ if (authMethod.claims_scopes.length === 0) {
+ authMethod.claims_scopes = [{ value: '' }];
+ }
}
if (authMethod.signing_algorithms) {
authMethod.signing_algorithms = structuredClone(
authMethod.signing_algorithms,
);
+ if (authMethod.signing_algorithms.length === 0) {
+ authMethod.signing_algorithms = [{ value: '' }];
+ }
}
if (authMethod.allowed_audiences) {
authMethod.allowed_audiences = structuredClone(
authMethod.allowed_audiences,
);
+ if (authMethod.allowed_audiences.length === 0) {
+ authMethod.allowed_audiences = [{ value: '' }];
+ }
}
if (authMethod.idp_ca_certs) {
authMethod.idp_ca_certs = structuredClone(authMethod.idp_ca_certs);
+ if (authMethod.idp_ca_certs.length === 0) {
+ authMethod.idp_ca_certs = [{ value: '' }];
+ }
}
if (authMethod.account_claim_maps) {
authMethod.account_claim_maps = structuredClone(
diff --git a/ui/admin/app/routes/scopes/scope/auth-methods/new.js b/ui/admin/app/routes/scopes/scope/auth-methods/new.js
index 8e7a59fce..5a9833da7 100644
--- a/ui/admin/app/routes/scopes/scope/auth-methods/new.js
+++ b/ui/admin/app/routes/scopes/scope/auth-methods/new.js
@@ -49,9 +49,13 @@ export default class ScopesScopeAuthMethodsNewRoute extends Route {
});
record.scopeModel = scopeModel;
- // if the auth method type is OIDC, initialize account_claim_maps with an empty row
+ // If the auth-method is of type OIDC, initialize the keyValue fields with an empty object.
if (params.type === TYPE_AUTH_METHOD_OIDC) {
record.account_claim_maps = [{ key: '', value: '' }];
+ record.claims_scopes = [{ value: '' }];
+ record.allowed_audiences = [{ value: '' }];
+ record.signing_algorithms = [{ value: '' }];
+ record.idp_ca_certs = [{ value: '' }];
}
return record;
diff --git a/ui/admin/tests/acceptance/auth-methods/selectors.js b/ui/admin/tests/acceptance/auth-methods/selectors.js
index f3b0d8fef..df9f6f8a2 100644
--- a/ui/admin/tests/acceptance/auth-methods/selectors.js
+++ b/ui/admin/tests/acceptance/auth-methods/selectors.js
@@ -9,34 +9,41 @@ export const FIELD_CLIENT_ID = '[name=client_id]';
export const FIELD_CLIENT_ID_VALUE = 'Client id value';
export const FIELD_CLIENT_SECRET = '[name=client_secret]';
export const FIELD_CLIENT_SECRET_VALUE = 'Client secret value';
-export const FIELD_SIGNING_ALGORITHMS = '[name=signing_algorithms] select';
+export const FIELD_SIGNING_ALGORITHMS =
+ '[name=signing_algorithms] [data-test-value-input]';
export const FIELD_SIGNING_ALGORITHMS_VALUE = 'RS384';
-export const FIELD_SIGNING_ALGORITHMS_ADD_BTN = '[data-test-add-option-button]';
+export const FIELD_SIGNING_ALGORITHMS_ADD_BTN =
+ '[name=signing_algorithms] [data-test-add-button]';
export const FIELD_SIGNING_ALGORITHMS_DELETE_BTN =
- '[name=signing_algorithms] tbody td:last-child button[aria-label=Remove]';
-export const FIELD_ALLOWED_AUDIENCES = '[name=allowed_audiences] input';
+ '[name=signing_algorithms] [data-test-delete-button]';
+export const FIELD_ALLOWED_AUDIENCES =
+ '[name=allowed_audiences] [data-test-value-input]';
export const FIELD_ALLOWED_AUDIENCES_VALUE = 'Allowed audiences';
export const FIELD_ALLOWED_AUDIENCES_ADD_BTN =
- '[name=allowed_audiences] button';
+ '[name=allowed_audiences] [data-test-add-button]';
export const FIELD_ALLOWED_AUDIENCES_DELETE_BTN =
- '[name=allowed_audiences] tbody td:last-child button[aria-label=Remove]';
-export const FIELD_CLAIMS_SCOPES = '[name=claims_scopes] input';
+ '[name=allowed_audiences] [data-test-delete-button]';
+export const FIELD_CLAIMS_SCOPES =
+ '[name=claims_scopes] [data-test-value-input]';
export const FIELD_CLAIMS_SCOPES_VALUE = 'Claim scopes';
-export const FIELD_CLAIMS_SCOPES_ADD_BTN = '[name=claims_scopes] button';
+export const FIELD_CLAIMS_SCOPES_ADD_BTN =
+ '[name=claims_scopes] [data-test-add-button]';
export const FIELD_CLAIMS_SCOPES_DELETE_BTN =
- '[name=claims_scopes] tbody td:last-child button[aria-label=Remove]';
+ '[name=claims_scopes] [data-test-delete-button]';
export const FIELD_ACCOUNT_CLAIM_MAPS_FROM_CLAIM =
'[name=account_claim_maps] [data-test-key-input]';
export const FIELD_ACCOUNT_CLAIM_MAPS_FROM_CLAIM_VALUE = 'from_claim';
export const FIELD_ACCOUNT_CLAIM_MAPS_TO_CLAIM =
'[name=account_claim_maps] [data-test-value-input]';
export const FIELD_ACCOUNT_CLAIM_MAPS_TO_CLAIM_VALUE = 'email';
-export const FIELD_ACCOUNT_CLAIM_MAPS_DELETE_BTN = '[data-test-delete-button]';
-export const FIELD_IDP_CERTS = '[name=idp_ca_certs] textarea';
+export const FIELD_ACCOUNT_CLAIM_MAPS_DELETE_BTN =
+ '[name=account_claim_maps] [data-test-delete-button]';
+export const FIELD_IDP_CERTS = '[name=idp_ca_certs] [data-test-value-input]';
export const FIELD_IDP_CERTS_VALUE = 'IDP certificates';
-export const FIELD_IDP_CERTS_ADD_BTN = '[name=idp_ca_certs] button';
+export const FIELD_IDP_CERTS_ADD_BTN =
+ '[name=idp_ca_certs] [data-test-add-button]';
export const FIELD_IDP_CERTS_DELETE_BTN =
- '[name=idp_ca_certs] tbody td:last-child button[aria-label=Remove]';
+ '[name=idp_ca_certs] [data-test-delete-button]';
export const FIELD_MAX_AGE = '[name=max_age]';
export const FIELD_MAX_AGE_VALUE = '5';
export const FIELD_API_URL_PREFIX = '[name=api_url_prefix]';
diff --git a/ui/admin/tests/acceptance/auth-methods/update-test.js b/ui/admin/tests/acceptance/auth-methods/update-test.js
index 4f4b63bed..f917ce9fe 100644
--- a/ui/admin/tests/acceptance/auth-methods/update-test.js
+++ b/ui/admin/tests/acceptance/auth-methods/update-test.js
@@ -132,7 +132,6 @@ module('Acceptance | auth-methods | update', function (hooks) {
selectors.FIELD_SIGNING_ALGORITHMS,
selectors.FIELD_SIGNING_ALGORITHMS_VALUE,
);
- await click(selectors.FIELD_SIGNING_ALGORITHMS_ADD_BTN);
// Remove all allowed audiences
const allowedAudiencesList = findAll(
@@ -147,7 +146,6 @@ module('Acceptance | auth-methods | update', function (hooks) {
selectors.FIELD_ALLOWED_AUDIENCES,
selectors.FIELD_ALLOWED_AUDIENCES_VALUE,
);
- await click(selectors.FIELD_ALLOWED_AUDIENCES_ADD_BTN);
// Remove all claims scopes
const claimsScopeList = await Promise.all(
@@ -162,7 +160,6 @@ module('Acceptance | auth-methods | update', function (hooks) {
selectors.FIELD_CLAIMS_SCOPES,
selectors.FIELD_CLAIMS_SCOPES_VALUE,
);
- await click(selectors.FIELD_CLAIMS_SCOPES_ADD_BTN);
// Remove all claim maps
const claimMaps = await Promise.all(