diff --git a/addons/api/addon/models/session.js b/addons/api/addon/models/session.js index 406c10c6c..b71a7bb13 100644 --- a/addons/api/addon/models/session.js +++ b/addons/api/addon/models/session.js @@ -3,7 +3,6 @@ import { computed } from '@ember/object'; import { equal } from '@ember/object/computed'; import { tracked } from '@glimmer/tracking'; import { A } from '@ember/array'; -import { typeOf } from '@ember/utils'; /** * @@ -44,20 +43,29 @@ class SessionCredential { // =attributes rawCredential; library; - #rawSecretValue; + #payloadSecret; /** + * The incoming payload may contain a JSON object under the `decoded` key only + * if it can be JSON-decoded. Some credential stores may not provide JSON, + * however, in which case we may have only the raw base64-encoded secret + * string. In the former case, we convert the key/value pairs of the JSON to + * an array of `SecretItem` instances. In the latter case, we return an + * array containing a single `SecretItem` instance with key `secret` and a + * string value equal to the base64-decoded raw secret. * The credential secret as an array of key/value objects. * @type {SessionCredential.SecretItem[]} */ get secrets() { - if (typeOf(this.#rawSecretValue) === 'object') { - return Object.keys(this.#rawSecretValue).map( - (key) => - new SessionCredential.SecretItem(key, this.#rawSecretValue[key]) + if (this.#payloadSecret?.decoded) { + const secretJSON = this.#payloadSecret.decoded; + return Object.keys(secretJSON).map( + (key) => new SessionCredential.SecretItem(key, secretJSON[key]) ); } else { - return [new SessionCredential.SecretItem('secret', this.#rawSecretValue)]; + // decode from base64 + const decodedString = atob(this.#payloadSecret.raw); + return [new SessionCredential.SecretItem('secret', decodedString)]; } } @@ -66,7 +74,7 @@ class SessionCredential { constructor(cred) { const { id, name, description, type } = cred.credential_library; this.library = new SessionCredential.Library(id, name, description, type); - this.#rawSecretValue = cred.secret; + this.#payloadSecret = cred.secret; this.rawCredential = cred; } } diff --git a/addons/api/mirage/scenarios/ipc.js b/addons/api/mirage/scenarios/ipc.js index a255cff3d..04ff375d4 100644 --- a/addons/api/mirage/scenarios/ipc.js +++ b/addons/api/mirage/scenarios/ipc.js @@ -53,6 +53,12 @@ export default function initializeMockIPC(server) { type, created_time: new Date().toISOString(), }); + const decoded = { + key1: 'value 1', + key2: true, + key3: 'test', + }; + const raw = btoa(JSON.stringify(decoded)); return { address: window.location.hostname, port: datatype.number(), @@ -67,7 +73,9 @@ export default function initializeMockIPC(server) { credential_store_id: 'csvlt_Q1HFGt7Jpm', type: 'vault', }, - secret: 'just-a-random-string', + secret: { + raw: btoa('just-a-random-string'), + }, }, { credential_library: { @@ -78,21 +86,10 @@ export default function initializeMockIPC(server) { type: 'vault', }, secret: { - key1: 'value 1', - key2: true, - key3: 'test', + raw, + decoded, }, }, - { - credential_library: { - id: 'clvlt_9KWscxpcY7', - name: 'Library Name', - description: 'Library Description', - credential_store_id: 'csvlt_Q1HFGt7Jpm', - type: 'vault', - }, - secret: 'just-a-random-string', - }, { credential_library: { id: 'clvlt_9KWscxpcY7', @@ -102,9 +99,20 @@ export default function initializeMockIPC(server) { type: 'vault', }, secret: { - key1: 'value 1', - key2: true, - key3: 'test', + raw: btoa('just-a-random-string'), + }, + }, + { + credential_library: { + id: 'clvlt_9KWscxpcY7', + name: 'Library Name', + description: 'Library Description', + credential_store_id: 'csvlt_Q1HFGt7Jpm', + type: 'vault', + }, + secret: { + raw, + decoded, }, }, ], 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 abc18784f..7d43d2e67 100644 --- a/ui/admin/app/components/form/auth-method/oidc/index.hbs +++ b/ui/admin/app/components/form/auth-method/oidc/index.hbs @@ -180,7 +180,11 @@ @style='warning' @iconOnly='trash' title={{t 'actions.remove'}} - @disabled={{if form.isEditable false true}} + @disabled={{if + @model.isNew + false + (if form.isEditable false true) + }} {{on 'click' (fn @removeItemByIndex 'attributes.signing_algorithms' i) @@ -215,7 +219,11 @@ {