diff --git a/addons/api/addon/adapters/application.js b/addons/api/addon/adapters/application.js
index 279e9b73f..12112ed67 100644
--- a/addons/api/addon/adapters/application.js
+++ b/addons/api/addon/adapters/application.js
@@ -248,7 +248,11 @@ export default class ApplicationAdapter extends RESTAdapter.extend(
// Normalize field-specific errors, if any.
const errors = fieldErrors.map((error) => ({
detail: error.description,
- source: { pointer: `/data/attributes/${error.name}` },
+ // Ember Data cannot handle errors on nested attributes, so these are
+ // flattened (e.g. `attributes.foobar` becomes `attributes_foobar`).
+ // To capture these errors, add read-only fields on the model
+ // corresponding to the underscored field name.
+ source: { pointer: `/data/attributes/${error.name.replace('.', '_')}` },
}));
// Return a list of JSON API errors rooted under the `errors` key.
return {
diff --git a/addons/api/addon/models/auth-method.js b/addons/api/addon/models/auth-method.js
index dc03abc0d..66f34757d 100644
--- a/addons/api/addon/models/auth-method.js
+++ b/addons/api/addon/models/auth-method.js
@@ -1,4 +1,5 @@
import GeneratedAuthMethodModel from '../generated/models/auth-method';
+import { attr } from '@ember-data/model';
import { fragment } from 'ember-data-model-fragments/attributes';
import { equal } from '@ember/object/computed';
@@ -27,6 +28,26 @@ export const options = {
};
export default class AuthMethodModel extends GeneratedAuthMethodModel {
+ // =error attributes
+ // These attributes exist solely to capture errors on nested fields.
+ // See the application adapter's error normalization method for
+ // more information.
+
+ @attr('string', { readOnly: true }) attributes_state;
+ @attr('string', { readOnly: true }) attributes_issuer;
+ @attr('string', { readOnly: true }) attributes_client_id;
+ @attr('string', { readOnly: true }) attributes_client_secret;
+ @attr('string', { readOnly: true }) attributes_max_age;
+ @attr('string', { readOnly: true }) attributes_api_url_prefix;
+ @attr('string', { readOnly: true })
+ attributes_disable_discovered_config_validation;
+ @attr('string', { readOnly: true }) attributes_dry_run;
+ @attr('string', { readOnly: true }) attributes_account_claim_maps;
+ @attr('string', { readOnly: true }) attributes_claims_scopes;
+ @attr('string', { readOnly: true }) attributes_signing_algorithms;
+ @attr('string', { readOnly: true }) attributes_allowed_audiences;
+ @attr('string', { readOnly: true }) attributes_idp_ca_certs;
+
// =attributes
/**
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 335392e08..e1a5592c0 100644
--- a/ui/admin/app/components/form/auth-method/oidc/index.hbs
+++ b/ui/admin/app/components/form/auth-method/oidc/index.hbs
@@ -57,13 +57,13 @@
@value={{@model.attributes.issuer}}
@label={{t 'form.issuer.label'}}
@helperText={{t 'form.issuer.help'}}
- @error={{@model.errors.attributes.issuer}}
+ @error={{@model.errors.attributes_issuer}}
readonly={{false}}
as |field|
>
- {{#if @model.errors.attributes.issuer}}
+ {{#if @model.errors.attributes_issuer}}
- {{#each @model.errors.attributes.issuer as |error|}}
+ {{#each @model.errors.attributes_issuer as |error|}}
{{error.message}}
{{/each}}
@@ -86,13 +86,13 @@
@value={{@model.attributes.client_id}}
@label={{t 'form.client_id.label'}}
@helperText={{t 'form.client_id.help'}}
- @error={{@model.errors.attributes.client_id}}
+ @error={{@model.errors.attributes_client_id}}
readonly={{false}}
as |field|
>
- {{#if @model.errors.attributes.client_id}}
+ {{#if @model.errors.attributes_client_id}}
- {{#each @model.errors.attributes.client_id as |error|}}
+ {{#each @model.errors.attributes_client_id as |error|}}
{{error.message}}
{{/each}}
@@ -105,13 +105,13 @@
@value={{@model.attributes.client_secret}}
@label={{t 'form.client_secret.label'}}
@helperText={{t 'form.client_secret.help'}}
- @error={{@model.errors.attributes.client_secret}}
+ @error={{@model.errors.attributes_client_secret}}
readonly={{false}}
as |field|
>
- {{#if @model.errors.attributes.client_secret}}
+ {{#if @model.errors.attributes_client_secret}}
- {{#each @model.errors.attributes.client_secret as |error|}}
+ {{#each @model.errors.attributes_client_secret as |error|}}
{{error.message}}
{{/each}}
@@ -123,6 +123,13 @@
<:title>{{t 'form.signing_algorithms.label'}}
<:description>{{t 'form.signing_algorithms.help'}}
<:body>
+ {{#if @model.errors.attributes_signing_algorithms}}
+
+ {{#each @model.errors.attributes_signing_algorithms as |error|}}
+ {{error.message}}
+ {{/each}}
+
+ {{/if}}
@@ -136,7 +143,7 @@
{{algorithm}}
{{/each}}
- {{#if @model.errors.attributes.signing_algorithms}}
-
- {{#each
- @model.errors.attributes.signing_algorithms
- as |error|
- }}
- {{error.message}}
- {{/each}}
-
- {{/if}}
@@ -225,6 +222,13 @@
<:title>{{t 'form.allowed_audiences.label'}}
<:description>{{t 'form.allowed_audiences.help'}}
<:body>
+ {{#if @model.errors.attributes_allowed_audiences}}
+
+ {{#each @model.errors.attributes_allowed_audiences as |error|}}
+ {{error.message}}
+ {{/each}}
+
+ {{/if}}
@@ -239,22 +243,12 @@
{{t 'form.claim.label'}}
- {{#if @model.errors.attributes.allowed_audiences}}
-
- {{#each
- @model.errors.attributes.allowed_audiences
- as |error|
- }}
- {{error.message}}
- {{/each}}
-
- {{/if}}
@@ -310,6 +304,13 @@
<:title>{{t 'form.claims_scopes.label'}}
<:description>{{t 'form.claims_scopes.help'}}
<:body>
+ {{#if @model.errors.attributes_claims_scopes}}
+
+ {{#each @model.errors.attributes_claims_scopes as |error|}}
+ {{error.message}}
+ {{/each}}
+
+ {{/if}}
@@ -324,22 +325,12 @@
{{t 'form.claims_scope.label'}}
- {{#if @model.errors.attributes.claims_scopes}}
-
- {{#each
- @model.errors.attributes.claims_scopes
- as |error|
- }}
- {{error.message}}
- {{/each}}
-
- {{/if}}
@@ -395,6 +386,13 @@
<:title>{{t 'form.account_claim_maps.label'}}
<:description>{{t 'form.account_claim_maps.help'}}
<:body>
+ {{#if @model.errors.attributes_account_claim_maps}}
+
+ {{#each @model.errors.attributes_account_claim_maps as |error|}}
+ {{error.message}}
+ {{/each}}
+
+ {{/if}}
@@ -410,28 +408,18 @@
{{t 'form.from_claim.label'}}
- {{#if @model.errors.attributes.account_claim_maps}}
-
- {{#each
- @model.errors.attributes.account_claim_maps
- as |error|
- }}
- {{error.message}}
- {{/each}}
-
- {{/if}}
{{toClaim}}
{{/each}}
- {{#if @model.errors.attributes.account_claim_maps}}
-
- {{#each
- @model.errors.attributes.account_claim_maps
- as |error|
- }}
- {{error.message}}
- {{/each}}
-
- {{/if}}
@@ -521,6 +499,13 @@
<:title>{{t 'form.idp_ca_certs.label'}}
<:description>{{t 'form.idp_ca_certs.help'}}
<:body>
+ {{#if @model.errors.attributes_idp_ca_certs}}
+
+ {{#each @model.errors.attributes_idp_ca_certs as |error|}}
+ {{error.message}}
+ {{/each}}
+
+ {{/if}}
@@ -534,19 +519,12 @@
{{t 'form.certificate.label'}}
- {{#if @model.errors.attributes.idp_ca_certs}}
-
- {{#each @model.errors.attributes.idp_ca_certs as |error|}}
- {{error.message}}
- {{/each}}
-
- {{/if}}
@@ -600,15 +578,15 @@
@value={{@model.attributes.max_age}}
@label={{t 'form.max_age.label'}}
@helperText={{t 'form.max_age.help'}}
- @error={{@model.errors.attributes.max_age}}
+ @error={{@model.errors.attributes_max_age}}
readonly={{false}}
step='1'
min='0'
as |field|
>
- {{#if @model.errors.attributes.max_age}}
+ {{#if @model.errors.attributes_max_age}}
- {{#each @model.errors.attributes.max_age as |error|}}
+ {{#each @model.errors.attributes_max_age as |error|}}
{{error.message}}
{{/each}}
@@ -621,13 +599,13 @@
@value={{@model.attributes.api_url_prefix}}
@label={{t 'form.api_url_prefix.label'}}
@helperText={{t 'form.api_url_prefix.help'}}
- @error={{@model.errors.attributes.api_url_prefix}}
+ @error={{@model.errors.attributes_api_url_prefix}}
readonly={{false}}
as |field|
>
- {{#if @model.errors.attributes.api_url_prefix}}
+ {{#if @model.errors.attributes_api_url_prefix}}
- {{#each @model.errors.attributes.api_url_prefix as |error|}}
+ {{#each @model.errors.attributes_api_url_prefix as |error|}}
{{error.message}}
{{/each}}