manual merge

This commit is contained in:
Randall Morey committed 2021-06-02 14:25:19 -04:00
commit 2804b4322b
16 files changed
+633 -28

No files matched your search

+5 -1
View File
@@ -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 {
+21
View File
@@ -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';
@@ -29,6 +30,26 @@ export const options = {
export default class AuthMethodModel extends GeneratedAuthMethodModel {
STATES_ENUM = options.oidc.state;
// =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
/**
+2
View File
@@ -27,6 +27,8 @@ titles:
abandon-confirm: Discard unsaved changes?
toggle-color-theme: Toggle Color Theme
welcome-to-boundary: Welcome to Boundary
label: Label
value: Value
descriptions:
empty-set: There are no items to display yet. You may be able to add items or try back later.
origin-initialization: To get started, please enter your origin URL
+31 -1
View File
@@ -59,7 +59,7 @@ client_id:
help: An OAuth 2.0 Client Identifier valid at the Authorization Server.
client_secret:
label: Client Secret
description: The client secret is set-only, may not be unset, and will not appear after a successful save.
help: The client secret is set-only and may not be unset.
max_age:
label: Maximum Age
help: The OIDC "max_age" parameter sent to the Authorization Server indicating a maximum acceptable time in seconds since the user's last authentication before requiring the user to reauthenticate. 0 indicates an immediate need to reauthenticate.
@@ -70,3 +70,33 @@ disable_discovered_config_validation:
label: Disable discovered config validation
help: >
If the Authorization Server's discovered configuration contains values that do not match the configuration set on this auth method, this can be set to force the local configuration to override the discovered values. This is useful in the case of slow-changing or incorrect values announced by the Authorization Server. NOTE: For safety, not providing this value will be treated the same as "false"; that is, every time the method is updated or the state is changed, this value must be set to "true" or it will be disabled.
idp_ca_certs:
label: Certificates
help: Optional PEM-encoded X.509 CA certificates that can be used as trust anchors when connecting to an OIDC provider.
certificate:
label: Certificate
allowed_audiences:
label: Allowed Audiences
help: Allowed audience claims for this auth method.
claim:
label: Claim
claims_scopes:
label: Claims Scopes
help: Optional claims scopes that will be requested during authentication.
claims_scope:
label: Claims Scope
account_claim_maps:
label: Account Claim Maps
help: >
Optional claim maps from custom claims to the standard claims of sub, name and email. These maps are represented as key=value where the key equals the from_claim and the value equals the to_claim. For example "oid=sub".
account_claim_map:
label: Account Claim Map
from_claim:
label: From Claim
to_claim:
label: To Claim
signing_algorithms:
label: Signing Algorithms
help: The signing algorithms allowed for the auth method.
algorithm:
label: Algorithm
@@ -30,6 +30,13 @@ auth-method:
pending:
title: Authentication Pending
description: Complete authentication in the newly-opened window.
titles:
new-signing-algorithm: New Signing Algorithm
new-allowed-audience: New Allowed Audience
new-claims-scope: New Claims Scope
new-from-claim: New From Claim
new-to-claim: New To Claim
new-certificate: New Certificate
types:
password: Password
oidc: OIDC
@@ -30,5 +30,6 @@
cancel=this.handleCancel
enableEdit=this.enableEdit
)
isEditable=this.isEditable
)}}
</form>
@@ -2,6 +2,8 @@
@use '../../utilities/type';
.rose-form-fieldset {
margin-bottom: sizing.rems(m);
.rose-form-fieldset-title {
@include type.type(l, bold);
}
@@ -11,13 +11,19 @@
}
// This styles are add to stop the input to apply extra margin (default on forms)
.rose-form-input,
.rose-form-input-field,
.rose-form-select,
.rose-form-input {
.rose-form-select-field {
margin: 0;
width: 100%;
}
// Fix margin issue with textarea elements inside tables
textarea {
display: block;
}
.rose-table-cell,
.rose-table-header-cell {
vertical-align: middle;
@@ -4,5 +4,8 @@
model=@model
submit=@submit
cancel=@cancel
removeItemByIndex=@removeItemByIndex
addStringItem=@addStringItem
addAccountClaimMapItem=@addAccountClaimMapItem
}}
{{/if}}
@@ -39,7 +39,6 @@
@label={{t 'form.description.label'}}
@helperText={{t 'form.description.help'}}
@error={{@model.errors.description}}
disabled={{@model.isSaving}}
readonly={{false}}
as |field|
>
@@ -58,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}}
<field.errors as |errors|>
{{#each @model.errors.attributes.issuer as |error|}}
{{#each @model.errors.attributes_issuer as |error|}}
<errors.message>{{error.message}}</errors.message>
{{/each}}
</field.errors>
@@ -87,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}}
<field.errors as |errors|>
{{#each @model.errors.attributes.client_id as |error|}}
{{#each @model.errors.attributes_client_id as |error|}}
<errors.message>{{error.message}}</errors.message>
{{/each}}
</field.errors>
@@ -106,34 +105,488 @@
@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}}
<field.errors as |errors|>
{{#each @model.errors.attributes.client_secret as |error|}}
{{#each @model.errors.attributes_client_secret as |error|}}
<errors.message>{{error.message}}</errors.message>
{{/each}}
</field.errors>
{{/if}}
</form.input>
{{! Signing Algorithms }}
<Rose::Form::Fieldset>
<:title>{{t 'form.signing_algorithms.label'}}</:title>
<:description>{{t 'form.signing_algorithms.help'}}</:description>
<:body>
{{#if @model.errors.attributes_signing_algorithms}}
<Rose::Form::Errors as |errors|>
{{#each @model.errors.attributes_signing_algorithms as |error|}}
<errors.message>{{error.message}}</errors.message>
{{/each}}
</Rose::Form::Errors>
{{/if}}
<Rose::Table @style='condensed' as |table|>
<table.header as |header|>
<header.row @hidden={{true}} as |row|>
<row.headerCell>{{t 'titles.value'}}</row.headerCell>
<row.headerCell>{{t 'titles.actions'}}</row.headerCell>
</header.row>
</table.header>
<table.body as |body|>
{{#each @model.attributes.signing_algorithms as |algorithm i|}}
<body.row as |row|>
<row.cell>
<form.select
@value={{algorithm.value}}
@error={{@model.errors.attributes_signing_algorithms}}
@contextual={{true}}
@onChange={{fn (mut algorithm.value)}}
as |field|
>
<field.label>{{t 'form.algorithm.label'}}</field.label>
<field.field as |select|>
{{#each this.signingAlgorithms as |algorithm|}}
<select.option
@value={{algorithm}}
>{{algorithm}}</select.option>
{{/each}}
</field.field>
</form.select>
</row.cell>
<row.cell @shrink={{true}}>
<Rose::Button
@style='warning'
@iconOnly='trash'
title={{t 'actions.remove'}}
@disabled={{if form.isEditable false true}}
{{on
'click'
(fn @removeItemByIndex 'attributes.signing_algorithms' i)
}}
>
{{t 'actions.remove'}}
</Rose::Button>
</row.cell>
</body.row>
{{/each}}
<body.row as |row|>
<row.cell>
<form.select
@value={{this.newSigningAlgorithm}}
@label={{t
'resources.auth-method.titles.new-signing-algorithm'
}}
@onChange={{fn (mut this.newSigningAlgorithm)}}
as |field|
>
<field.field as |select|>
{{#each this.signingAlgorithms as |algorithm|}}
<select.option
@value={{algorithm}}
>{{algorithm}}</select.option>
{{/each}}
</field.field>
</form.select>
</row.cell>
<row.cell @shrink={{true}}>
<Rose::Button
@style='secondary'
title={{t 'actions.add'}}
@disabled={{if form.isEditable false true}}
{{on
'click'
(fn
@addStringItem
'attributes.signing_algorithms'
this.newSigningAlgorithm
)
}}
>
{{t 'actions.add'}}
</Rose::Button>
</row.cell>
</body.row>
</table.body>
</Rose::Table>
</:body>
</Rose::Form::Fieldset>
{{! Allowed Audiences }}
<Rose::Form::Fieldset>
<:title>{{t 'form.allowed_audiences.label'}}</:title>
<:description>{{t 'form.allowed_audiences.help'}}</:description>
<:body>
{{#if @model.errors.attributes_allowed_audiences}}
<Rose::Form::Errors as |errors|>
{{#each @model.errors.attributes_allowed_audiences as |error|}}
<errors.message>{{error.message}}</errors.message>
{{/each}}
</Rose::Form::Errors>
{{/if}}
<Rose::Table @style='condensed' as |table|>
<table.header as |header|>
<header.row @hidden={{true}} as |row|>
<row.headerCell>{{t 'titles.value'}}</row.headerCell>
<row.headerCell>{{t 'titles.actions'}}</row.headerCell>
</header.row>
</table.header>
<table.body as |body|>
{{#each @model.attributes.allowed_audiences as |audience i|}}
<body.row as |row|>
<row.cell>
<form.input
@type='text'
@value={{audience.value}}
@error={{@model.errors.attributes_allowed_audiences}}
@contextual={{true}}
as |field|
>
<field.label>{{t 'form.claim.label'}}</field.label>
<field.field />
</form.input>
</row.cell>
<row.cell @shrink={{true}}>
<Rose::Button
@style='warning'
@iconOnly='trash'
title={{t 'actions.remove'}}
@disabled={{if form.isEditable false true}}
{{on
'click'
(fn @removeItemByIndex 'attributes.allowed_audiences' i)
}}
>
{{t 'actions.remove'}}
</Rose::Button>
</row.cell>
</body.row>
{{/each}}
<body.row as |row|>
<row.cell>
<form.input
@type='text'
@value={{this.newAllowedAudience}}
@label={{t 'resources.auth-method.titles.new-allowed-audience'}}
/>
</row.cell>
<row.cell @shrink={{true}}>
<Rose::Button
@style='secondary'
title={{t 'actions.add'}}
@disabled={{if form.isEditable false true}}
{{on
'click'
(fn
@addStringItem
'attributes.allowed_audiences'
this.newAllowedAudience
)
}}
>
{{t 'actions.add'}}
</Rose::Button>
</row.cell>
</body.row>
</table.body>
</Rose::Table>
</:body>
</Rose::Form::Fieldset>
{{! Claims Scopes }}
<Rose::Form::Fieldset>
<:title>{{t 'form.claims_scopes.label'}}</:title>
<:description>{{t 'form.claims_scopes.help'}}</:description>
<:body>
{{#if @model.errors.attributes_claims_scopes}}
<Rose::Form::Errors as |errors|>
{{#each @model.errors.attributes_claims_scopes as |error|}}
<errors.message>{{error.message}}</errors.message>
{{/each}}
</Rose::Form::Errors>
{{/if}}
<Rose::Table @style='condensed' as |table|>
<table.header as |header|>
<header.row @hidden={{true}} as |row|>
<row.headerCell>{{t 'titles.value'}}</row.headerCell>
<row.headerCell />
</header.row>
</table.header>
<table.body as |body|>
{{#each @model.attributes.claims_scopes as |claimsScope i|}}
<body.row as |row|>
<row.cell>
<form.input
@type='text'
@value={{claimsScope.value}}
@error={{@model.errors.attributes_claims_scopes}}
@contextual={{true}}
as |field|
>
<field.label>{{t 'form.claims_scope.label'}}</field.label>
<field.field />
</form.input>
</row.cell>
<row.cell @shrink={{true}}>
<Rose::Button
@style='warning'
@iconOnly='trash'
title={{t 'actions.remove'}}
@disabled={{if form.isEditable false true}}
{{on
'click'
(fn @removeItemByIndex 'attributes.claims_scopes' i)
}}
>
{{t 'actions.remove'}}
</Rose::Button>
</row.cell>
</body.row>
{{/each}}
<body.row as |row|>
<row.cell>
<form.input
@type='text'
@value={{this.newClaimsScope}}
@label={{t 'resources.auth-method.titles.new-claims-scope'}}
/>
</row.cell>
<row.cell @shrink={{true}}>
<Rose::Button
@style='secondary'
title={{t 'actions.add'}}
@disabled={{if form.isEditable false true}}
{{on
'click'
(fn
@addStringItem
'attributes.claims_scopes'
this.newClaimsScope
)
}}
>
{{t 'actions.add'}}
</Rose::Button>
</row.cell>
</body.row>
</table.body>
</Rose::Table>
</:body>
</Rose::Form::Fieldset>
{{! Account Claim Maps }}
<Rose::Form::Fieldset>
<:title>{{t 'form.account_claim_maps.label'}}</:title>
<:description>{{t 'form.account_claim_maps.help'}}</:description>
<:body>
{{#if @model.errors.attributes_account_claim_maps}}
<Rose::Form::Errors as |errors|>
{{#each @model.errors.attributes_account_claim_maps as |error|}}
<errors.message>{{error.message}}</errors.message>
{{/each}}
</Rose::Form::Errors>
{{/if}}
<Rose::Table @style='condensed' as |table|>
<table.header as |header|>
<header.row as |row|>
<row.headerCell>{{t 'form.from_claim.label'}}</row.headerCell>
<row.headerCell>{{t 'form.to_claim.label'}}</row.headerCell>
<row.headerCell>{{t 'titles.actions'}}</row.headerCell>
</header.row>
</table.header>
<table.body as |body|>
{{#each @model.attributes.account_claim_maps as |claimMap i|}}
<body.row as |row|>
<row.cell>
<form.input
@type='text'
@value={{claimMap.from}}
@error={{@model.errors.attributes_account_claim_maps}}
@contextual={{true}}
as |field|
>
<field.label>{{t 'form.from_claim.label'}}</field.label>
<field.field />
</form.input>
</row.cell>
<row.cell>
<form.select
@value={{claimMap.to}}
@error={{@model.errors.attributes_account_claim_maps}}
@contextual={{true}}
@onChange={{fn (mut claimMap.to)}}
as |field|
>
<field.label>{{t 'form.to_claim.label'}}</field.label>
<field.field as |select|>
{{#each this.toClaims as |toClaim|}}
<select.option
@value={{toClaim}}
>{{toClaim}}</select.option>
{{/each}}
</field.field>
</form.select>
</row.cell>
<row.cell @shrink={{true}}>
<Rose::Button
@style='warning'
@iconOnly='trash'
title={{t 'actions.remove'}}
@disabled={{if form.isEditable false true}}
{{on
'click'
(fn @removeItemByIndex 'attributes.account_claim_maps' i)
}}
>
{{t 'actions.remove'}}
</Rose::Button>
</row.cell>
</body.row>
{{/each}}
<body.row as |row|>
<row.cell>
<form.input
@type='text'
@value={{this.newFromClaim}}
@label={{t 'resources.auth-method.titles.new-from-claim'}}
/>
</row.cell>
<row.cell>
<form.select
@value={{this.newToClaim}}
@label={{t 'resources.auth-method.titles.new-to-claim'}}
@onChange={{fn (mut this.newToClaim)}}
as |field|
>
<field.field as |select|>
{{#each this.toClaims as |toClaim|}}
<select.option
@value={{toClaim}}
>{{toClaim}}</select.option>
{{/each}}
</field.field>
</form.select>
</row.cell>
<row.cell @shrink={{true}}>
<Rose::Button
@style='secondary'
title={{t 'actions.add'}}
@disabled={{if form.isEditable false true}}
{{on
'click'
(fn @addAccountClaimMapItem this.newFromClaim this.newToClaim)
}}
>
{{t 'actions.add'}}
</Rose::Button>
</row.cell>
</body.row>
</table.body>
</Rose::Table>
</:body>
</Rose::Form::Fieldset>
{{! Certificates }}
<Rose::Form::Fieldset>
<:title>{{t 'form.idp_ca_certs.label'}}</:title>
<:description>{{t 'form.idp_ca_certs.help'}}</:description>
<:body>
{{#if @model.errors.attributes_idp_ca_certs}}
<Rose::Form::Errors as |errors|>
{{#each @model.errors.attributes_idp_ca_certs as |error|}}
<errors.message>{{error.message}}</errors.message>
{{/each}}
</Rose::Form::Errors>
{{/if}}
<Rose::Table @style='condensed' as |table|>
<table.header as |header|>
<header.row @hidden={{true}} as |row|>
<row.headerCell>{{t 'titles.value'}}</row.headerCell>
<row.headerCell>{{t 'titles.actions'}}</row.headerCell>
</header.row>
</table.header>
<table.body as |body|>
{{#each @model.attributes.idp_ca_certs as |cert i|}}
<body.row as |row|>
<row.cell>
<form.textarea
@value={{cert.value}}
@error={{@model.errors.attributes_idp_ca_certs}}
@contextual={{true}}
as |field|
>
<field.label>{{t 'form.certificate.label'}}</field.label>
<field.field />
</form.textarea>
</row.cell>
<row.cell @shrink={{true}}>
<Rose::Button
@style='warning'
@iconOnly='trash'
title={{t 'actions.remove'}}
@disabled={{if form.isEditable false true}}
{{on
'click'
(fn @removeItemByIndex 'attributes.idp_ca_certs' i)
}}
>
{{t 'actions.remove'}}
</Rose::Button>
</row.cell>
</body.row>
{{/each}}
<body.row as |row|>
<row.cell>
<form.textarea
@value={{this.newCertificate}}
@label={{t 'resources.auth-method.titles.new-certificate'}}
/>
</row.cell>
<row.cell @shrink={{true}}>
<Rose::Button
@style='secondary'
title={{t 'actions.add'}}
@disabled={{if form.isEditable false true}}
{{on
'click'
(fn
@addStringItem 'attributes.idp_ca_certs' this.newCertificate
)
}}
>
{{t 'actions.add'}}
</Rose::Button>
</row.cell>
</body.row>
</table.body>
</Rose::Table>
</:body>
</Rose::Form::Fieldset>
<form.input
@name='max_age'
@type='number'
@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}}
<field.errors as |errors|>
{{#each @model.errors.attributes.max_age as |error|}}
{{#each @model.errors.attributes_max_age as |error|}}
<errors.message>{{error.message}}</errors.message>
{{/each}}
</field.errors>
@@ -146,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}}
<field.errors as |errors|>
{{#each @model.errors.attributes.api_url_prefix as |error|}}
{{#each @model.errors.attributes_api_url_prefix as |error|}}
<errors.message>{{error.message}}</errors.message>
{{/each}}
</field.errors>
@@ -0,0 +1,20 @@
import Component from '@glimmer/component';
import { options } from 'api/models/auth-method';
export default class FormAuthMethodOidcComponent extends Component {
// =attributes
/**
* @type {object}
*/
signingAlgorithms = options.oidc.signing_algorithms;
/**
* @type {object}
*/
toClaims = options.oidc.account_claim_maps.to;
/**
* @type {string}
*/
newSigningAlgorithm = options.oidc.signing_algorithms[0];
}
@@ -134,4 +134,45 @@ export default class ScopesScopeAuthMethodsRoute extends Route {
}
await authMethod.reload();
}
/**
* Removes an item from array `property` at `index` on the
* passed `authMethod`. This is used to manage entries in fragment array
* fields such as `signing_algorithms`.
* @param {AuthMethodModel} authMethod
* @param {string} property
* @param {number} index
*/
@action
async removeItemByIndex(authMethod, property, index) {
const array = authMethod.get(property);
array.removeAt(index);
}
/**
* Adds a string item to array `property` on the passed `authMethod`.
* This is used to manage entries in fragment OIDC string array fields such
* as `signing_algorithms`.
* @param {AuthMethodModel} authMethod
* @param {string} property
* @param {string} value
*/
@action
async addStringItem(authMethod, property, value) {
const array = authMethod.get(property);
array.addObject({ value });
}
/**
* Adds an account claim map fragment to the passed OIDC `authMethod`.
* @param {AuthMethodModel} authMethod
* @param {string} property
* @param {string} value
*/
@action
async addAccountClaimMapItem(authMethod, from, to) {
const array = authMethod.attributes.account_claim_maps;
const value = { from, to };
array.addObject(value);
}
}
+7 -5
View File
@@ -80,11 +80,13 @@
}
}
fieldset {
margin-bottom: sizing.rems(m);
legend {
@extend .rose-form-label;
.rose-form-fieldset {
.rose-table {
.rose-form-label {
position: absolute;
top: -9999px;
left: -9999px;
}
}
}
}
@@ -2,7 +2,15 @@
<nav.link @route='scopes.scope.auth-methods.auth-method.index'>
{{t 'titles.details'}}
</nav.link>
<nav.link @route='scopes.scope.auth-methods.auth-method.accounts'>
{{t 'resources.account.title_plural'}}
</nav.link>
{{#if @model.isOIDC}}
{{#if (feature-flag 'oidc-account-crud')}}
<nav.link @route='scopes.scope.auth-methods.auth-method.accounts'>
{{t 'resources.account.title_plural'}}
</nav.link>
{{/if}}
{{else}}
<nav.link @route='scopes.scope.auth-methods.auth-method.accounts'>
{{t 'resources.account.title_plural'}}
</nav.link>
{{/if}}
</Rose::Nav::Tabs>
@@ -2,4 +2,7 @@
@model={{@model}}
@submit={{route-action 'save' @model}}
@cancel={{route-action 'cancel' @model}}
@removeItemByIndex={{route-action 'removeItemByIndex' @model}}
@addStringItem={{route-action 'addStringItem' @model}}
@addAccountClaimMapItem={{route-action 'addAccountClaimMapItem' @model}}
/>
+3 -1
View File
@@ -88,7 +88,8 @@ module.exports = function (environment) {
featureFlags: {
'primary-auth-method': true,
oidc: true,
'oidc-crud': false,
'oidc-crud': true,
'oidc-account-crud': false,
search: false,
filter: false,
capabilities: false,
@@ -131,6 +132,7 @@ module.exports = function (environment) {
ENV.featureFlags['primary-auth-method'] = true;
ENV.featureFlags['oidc'] = true;
ENV.featureFlags['oidc-crud'] = true;
//ENV.featureFlags['oidc-account-crud'] = true;
}
if (environment === 'test') {